Fix cursor position issue with astral symbols

In case of astral symbols like Devanagari matras multiple wide-char codepoints
occupy a single position/column. Positioning the cursor wrt. the actual number
of wide-characters in a wide-char string gets "visually incorrect".  The trick
is to calculate the correct number of columns needed to represent a fixed-size
wide-character string.

Relevant man pages:

1. wcswidth(3)
2. wctomb(3)
3. mblen(3)

Interesting links:

1. https://www.gnu.org/software/libc/manual/html_node/Non_002dreentrant-Character-Conversion.html
2. https://www.gnu.org/software/libc/manual/html_node/Shift-State.html
3. https://10hash.com/c-programming/uchar/
4. https://mathiasbynens.be/notes/javascript-unicode#accounting-for-astral-symbols

Example file names for test:

1. Malgudi Days - मालगुडी डेज - E05. Swami and Friends - स्वामी और उसके दोस्त (Part 5)
2. Eso eso aamar ghare eso ♫ এসো এসো আমার ঘরে এসো ♫ Swagatalakshmi Dasgupta
3. Führer
This commit is contained in:
Arun Prakash Jana 2017-08-26 13:34:43 +05:30
parent ac03793547
commit c49b79d792
No known key found for this signature in database
GPG key ID: A75979F35C080412

7
nnn.c
View file

@ -44,6 +44,9 @@
#define _XOPEN_SOURCE_EXTENDED #define _XOPEN_SOURCE_EXTENDED
#endif #endif
#endif #endif
#ifndef __USE_XOPEN /* Fix failure due to wcswidth(), ncursesw/curses.h includes whcar.h on Ubuntu 14.04 */
#define __USE_XOPEN
#endif
#include <curses.h> #include <curses.h>
#include <dirent.h> #include <dirent.h>
#include <errno.h> #include <errno.h>
@ -64,13 +67,13 @@
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
#include <wchar.h>
#include <readline/history.h> #include <readline/history.h>
#include <readline/readline.h> #include <readline/readline.h>
#ifndef __USE_XOPEN_EXTENDED #ifndef __USE_XOPEN_EXTENDED
#define __USE_XOPEN_EXTENDED 1 #define __USE_XOPEN_EXTENDED 1
#endif #endif
#include <ftw.h> #include <ftw.h>
#include <wchar.h>
#include "config.h" #include "config.h"
@ -1026,7 +1029,7 @@ xreadline(char *fname)
while (1) { while (1) {
buf[len] = ' '; buf[len] = ' ';
mvaddnwstr(y, x, buf, len + 1); mvaddnwstr(y, x, buf, len + 1);
move(y, x + pos); move(y, x + wcswidth(buf, pos));
if ((r = get_wch(ch)) != ERR) { if ((r = get_wch(ch)) != ERR) {
if (r == OK) { if (r == OK) {