diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-06-07 11:48:44 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-06-07 11:52:42 -0700 |
commit | c2a7e41fae342531dbd0b8ba74136ad90b060817 (patch) | |
tree | 6b092206f48551feecca7f13b629fba1eae50322 | |
parent | 686a9e74ed82a08735cdf679195cbdda172706bd (diff) | |
download | uemacs-c2a7e41fae342531dbd0b8ba74136ad90b060817.tar.gz |
Turn ESC+'[' into a CSI character
This avoids the annoying behavior where we're on the command line,
waiting for an ESC, and any control character sequence ends up finishing
the command line and eating the first ESC.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | input.c | 3 | ||||
-rw-r--r-- | posix.c | 89 |
2 files changed, 58 insertions, 34 deletions
@@ -338,11 +338,14 @@ int getcmd(void) #if VT220 proc_metac: #endif + if (c == 128+27) /* CSI */ + goto handle_CSI; /* process META prefix */ if (c == (CONTROL | '[')) { c = get1key(); #if VT220 if (c == '[' || c == 'O') { /* CSI P.K. */ +handle_CSI: c = get1key(); if (c >= 'A' && c <= 'D') return (SPEC | c | cmask); @@ -168,26 +168,56 @@ void ttflush(void) */ int ttgetc(void) { - static unsigned char pending; + static unsigned char buffer[32]; + static int pending; unsigned char c, second; - int n; + int count; + + count = pending; + if (!count) { + count = read(0, buffer, sizeof(buffer)); + if (count <= 0) + return 0; + pending = count; + } + + c = buffer[0]; + if (c >= 32 && c < 128) + goto done; + + /* Special character - try to fill buffer */ + if (count == 1) { + int n; + ntermios.c_cc[VMIN] = 0; + ntermios.c_cc[VTIME] = 1; /* A .1 second lag */ + tcsetattr(0, TCSANOW, &ntermios); + + n = read(0, buffer + count, sizeof(buffer) - count); + + /* Undo timeout */ + ntermios.c_cc[VMIN] = 1; + ntermios.c_cc[VTIME] = 0; + tcsetattr(0, TCSANOW, &ntermios); - if (pending) { - c = pending; - pending = 0; - return c; + if (n <= 0) + goto done; + pending += n; } + second = buffer[1]; - n = read(0, &c, 1); - if (n != 1) - return 0; + /* Turn ESC+'[' into CSI */ + if (c == 27 && second == '[') { + pending -= 2; + memmove(buffer, buffer+2, pending); + return 128+27; + } if (!utf8_mode()) - return c; + goto done; /* Normal 7-bit? */ if (!(c & 0x80)) - return c; + goto done; /* * Unexpected UTF-8 continuation character? Maybe @@ -195,7 +225,7 @@ int ttgetc(void) * character.. Regardless, just pass it on. */ if (!(c & 0x40)) - return c; + goto done; /* * Multi-byte sequences.. Right now we only @@ -204,33 +234,24 @@ int ttgetc(void) * anything else.. */ if (c & 0x3c) - return c; + goto done; + + if ((second & 0xc0) != 0x80) + goto done; /* - * Two-byte sequence representing 0x80-0xff.. We want - * to do this read with a timeout. + * Ok, it's a two-byte UTF-8 character that can be represented + * as a single-byte Latin1 character! */ - ntermios.c_cc[VMIN] = 1; - ntermios.c_cc[VTIME] = 10; /* 1 second */ - tcsetattr(0, TCSANOW, &ntermios); - - n = read(0, &second, 1); - - /* Undo timeout */ - ntermios.c_cc[VTIME] = 0; - tcsetattr(0, TCSANOW, &ntermios); - - if (n != 1) - return c; - - if ((second & 0xc0) != 0x80) { - pending = second; - return c; - } - c = (c << 6) | (second & 0x3f); + pending -= 2; + memmove(buffer, buffer+2, pending); + + return c; - /* Ok, real UTF-8 character */ +done: + pending--; + memmove(buffer, buffer+1, pending); return c; } |