From 1455834a50b8b6a15567e971db664fe7a6cdfaf6 Mon Sep 17 00:00:00 2001 From: Nicholas Noll Date: Fri, 29 Oct 2021 17:46:41 -0700 Subject: fix(unicode): emoji widths and readline now moves in a more unicode aware manner --- sys/cmd/rc/input.c | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) (limited to 'sys/cmd') diff --git a/sys/cmd/rc/input.c b/sys/cmd/rc/input.c index 08363f0..5d30ccd 100644 --- a/sys/cmd/rc/input.c +++ b/sys/cmd/rc/input.c @@ -341,14 +341,16 @@ refreshsingleline(struct TerminalState *term) w = utf8·runewidth(r); buf+=n, len-=n; - pos-=w, col-=w; + pos-=w, col-=w; } assert(buf <= term->edit.buf + len); while(off+col > term->cursor.cap){ n = utf8·decodeprev(buf+len-1, &r); - len-=n, col--; + w = utf8·runewidth(r); + + len-=n, col-=w; } assert(len >= 0); @@ -510,8 +512,8 @@ insertrune(struct TerminalState *term, int n, char *c) memmove(term->edit.buf+term->edit.len+n, term->edit.buf+term->edit.len, term->edit.len-term->edit.pos); memcpy(term->edit.buf+term->edit.pos, c, n); - term->edit.pos+=n, term->edit.len+=n; - term->cursor.pos++, term->cursor.len++; + term->edit.pos += n, term->edit.len += n; + term->cursor.pos += w, term->cursor.len += w; term->edit.buf[term->edit.len] = '\0'; refreshline(term); @@ -664,15 +666,21 @@ static Position left(struct TerminalState *term, int n) { + int w, d; rune r; Position pos = CURRENT(term); char *buf = term->edit.buf + term->edit.pos; - pos.cursor = MAX(pos.cursor-n, 0); - - while(n-- > 0 && buf > term->edit.buf) + d = 0; + while(n > 0 && buf > term->edit.buf){ buf -= utf8·decodeprev(buf-1, &r); + w = utf8·runewidth(r); + n -= w; + d += w; + } + + pos.cursor = MAX(pos.cursor-d, 0); pos.buffer = MAX(buf-term->edit.buf, 0); return pos; } @@ -682,16 +690,22 @@ static Position right(struct TerminalState *term, int n) { + int w, d; rune r; Position pos = CURRENT(term); char *end = term->edit.buf + term->edit.len; char *buf = term->edit.buf + term->edit.pos; - pos.cursor = MIN(pos.cursor+n, term->cursor.len); - - while(n-- > 0 && buf < end) + d = 0; + while(n > 0 && buf < end){ buf += utf8·decode(buf, &r); + w = utf8·runewidth(r); + n -= w; + d += w; + } + + pos.cursor = MIN(pos.cursor+d, term->cursor.len); pos.buffer = MIN(buf-term->edit.buf, term->edit.len); return pos; } -- cgit v1.2.1