From 19f1943f6fb7d33f0351417f1e4fa27f45981da6 Mon Sep 17 00:00:00 2001 From: Joachim Nilsson Date: Fri, 30 Jul 2010 02:14:35 +0200 Subject: [PATCH] Initial, and very poor, UTF-8 support. --- src/editline.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++--- src/sysunix.c | 8 ++++++-- 2 files changed, 56 insertions(+), 5 deletions(-) diff --git a/src/editline.c b/src/editline.c index 43bd7bc..b022b89 100644 --- a/src/editline.c +++ b/src/editline.c @@ -135,6 +135,16 @@ static int is_alpha_num(unsigned char c) return 0; } +/* http://www.utf8-chartable.de/unicode-utf8-table.pl */ +int isutf8(unsigned char c) + { + if (c >= 0xC2 && c <= 0xCF) + return 1; + + return 0; +} + + /* ** TTY input/output functions. */ @@ -167,7 +177,15 @@ static void tty_puts(const char *p) static void tty_show(unsigned char c) { - if (c == DEL) { + static int mode_compose = 0; + + if (mode_compose) { + tty_put(c); + mode_compose = 0; + } else if (isutf8(c)) { + mode_compose = 1; + tty_put(c); + } else if (c == DEL) { tty_put('^'); tty_put('?'); } else if (ISCTL(c)) { @@ -325,7 +343,9 @@ static void left(el_status_t Change) { if (rl_point) { tty_back(); - if (ISMETA(rl_line_buffer[rl_point - 1])) { + if (isutf8(rl_line_buffer[rl_point - 2])) { + rl_point--; + } else if (ISMETA(rl_line_buffer[rl_point - 1])) { if (rl_meta_chars) { tty_back(); tty_back(); @@ -342,6 +362,9 @@ static void right(el_status_t Change) { tty_show(rl_line_buffer[rl_point]); + if (isutf8(rl_line_buffer[rl_point])) + tty_show(rl_line_buffer[++rl_point]); + if (Change == CSmove) rl_point++; } @@ -713,6 +736,9 @@ static el_status_t delete_string(int count) if (ISCTL(*p)) { i = 2; tty_put(' '); + } else if (isutf8(*p)) { + i = 2; + tty_put(' '); } else if (rl_meta_chars && ISMETA(*p)) { i = 3; tty_put(' '); @@ -887,6 +913,20 @@ static el_status_t meta(void) return ring_bell(); } +static el_status_t utf8(int c) +{ + char buff[3]; + + if (!isutf8(c)) + return CSeof; + + buff[0] = c; + buff[1] = tty_get(); + buff[2] = '\0'; + + return insert_string(buff); +} + static el_status_t emacs(int c) { el_status_t s; @@ -895,6 +935,10 @@ static el_status_t emacs(int c) /* Save point before interpreting input character 'c'. */ old_point = rl_point; + if (isutf8(c)) { + return utf8(c); + } + if (rl_meta_chars && ISMETA(c)) { tty_push(UNMETA(c)); return meta(); @@ -915,7 +959,10 @@ static el_status_t emacs(int c) static el_status_t tty_special(int c) { - if (rl_meta_chars && ISMETA(c)) + if (isutf8(c)) + return CSdispatch; + + if (rl_meta_chars && ISMETA(c)) return CSdispatch; if (c == rl_erase || c == DEL) diff --git a/src/sysunix.c b/src/sysunix.c index 4827f33..9765c7a 100644 --- a/src/sysunix.c +++ b/src/sysunix.c @@ -43,7 +43,9 @@ void rl_ttyset(int Reset) new = old; new.c_lflag &= ~(ECHO | ICANON | ISIG); - new.c_iflag &= ~(ISTRIP | INPCK); + new.c_iflag &= ~(ISTRIP | INPCK); /* | PARENB */ +// new.c_cflag &= ~(CSIZE); +// new.c_cflag |= (CS8 | CLOCAL); new.c_cc[VMIN] = 1; new.c_cc[VTIME] = 0; if (-1 == tcsetattr(0, TCSADRAIN, &new)) @@ -76,7 +78,9 @@ void rl_ttyset(int Reset) new = old; new.c_lflag &= ~(ECHO | ICANON | ISIG); - new.c_iflag &= ~(ISTRIP | INPCK); + new.c_iflag &= ~(ISTRIP | INPCK); /* | PARENB */ +// new.c_cflag &= ~(CSIZE); +// new.c_cflag |= (CS8 | CLOCAL); new.c_cc[VMIN] = 1; new.c_cc[VTIME] = 0; if (-1 == ioctl(0, TCSETAW, &new))