diff options
| author | 2017-08-26 13:34:43 +0530 | |
|---|---|---|
| committer | 2017-08-26 14:46:49 +0530 | |
| commit | c49b79d792a8a7d298b3d4dcd3dc1755a5a95060 (patch) | |
| tree | a800ab0c8ef718f30ee467785350a04dccfa07ba | |
| parent | ac037935475ba3e6589a27793adc94d58329b7e3 (diff) | |
| download | nnn-c49b79d792a8a7d298b3d4dcd3dc1755a5a95060.tar.gz | |
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
| -rw-r--r-- | nnn.c | 7 |
1 files changed, 5 insertions, 2 deletions
@@ -44,6 +44,9 @@ #define _XOPEN_SOURCE_EXTENDED #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 <dirent.h> #include <errno.h> @@ -64,13 +67,13 @@ #include <string.h> #include <time.h> #include <unistd.h> -#include <wchar.h> #include <readline/history.h> #include <readline/readline.h> #ifndef __USE_XOPEN_EXTENDED #define __USE_XOPEN_EXTENDED 1 #endif #include <ftw.h> +#include <wchar.h> #include "config.h" @@ -1026,7 +1029,7 @@ xreadline(char *fname) while (1) { buf[len] = ' '; mvaddnwstr(y, x, buf, len + 1); - move(y, x + pos); + move(y, x + wcswidth(buf, pos)); if ((r = get_wch(ch)) != ERR) { if (r == OK) { |