mirror of
https://github.com/sheumann/hush.git
synced 2024-12-28 22:30:05 +00:00
vi: add comments to Rob's algorithm of reading and matching ESC sequences
(nice work btw!)
This commit is contained in:
parent
5e38cd910a
commit
5373fbcd11
56
editors/vi.c
56
editors/vi.c
@ -2243,60 +2243,70 @@ static char readit(void) // read (maybe cursor) key from stdin
|
|||||||
|
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
||||||
// If no data, block waiting for input.
|
|
||||||
n = chars_to_parse;
|
n = chars_to_parse;
|
||||||
while (!n) {
|
if (n == 0) {
|
||||||
|
// If no data, block waiting for input.
|
||||||
n = safe_read(0, readbuffer, 1);
|
n = safe_read(0, readbuffer, 1);
|
||||||
if (n <= 0) {
|
if (n <= 0) {
|
||||||
|
error:
|
||||||
place_cursor(rows - 1, 0, FALSE); // go to bottom of screen
|
place_cursor(rows - 1, 0, FALSE); // go to bottom of screen
|
||||||
clear_to_eol(); // erase to end of line
|
clear_to_eol(); // erase to end of line
|
||||||
cookmode(); // terminal to "cooked"
|
cookmode(); // terminal to "cooked"
|
||||||
bb_error_msg_and_die("can't read user input");
|
bb_error_msg_and_die("can't read user input");
|
||||||
}
|
}
|
||||||
// Returning NUL from this routine would be bad.
|
|
||||||
if (*readbuffer) break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Grab character to return from buffer
|
// Grab character to return from buffer
|
||||||
c = *readbuffer;
|
c = readbuffer[0];
|
||||||
|
// Returning NUL from this routine would be bad.
|
||||||
|
if (c == '\0')
|
||||||
|
c = ' ';
|
||||||
n--;
|
n--;
|
||||||
if (n) memmove(readbuffer, readbuffer+1, n);
|
if (n) memmove(readbuffer, readbuffer + 1, n);
|
||||||
|
|
||||||
// If it's an escape sequence, loop through known matches.
|
// If it's an escape sequence, loop through known matches.
|
||||||
if (c == 27) {
|
if (c == 27) {
|
||||||
const struct esc_cmds *eindex;
|
const struct esc_cmds *eindex;
|
||||||
|
|
||||||
for (eindex = esccmds; eindex < esccmds+ARRAY_SIZE(esccmds); eindex++) {
|
for (eindex = esccmds; eindex < esccmds + ARRAY_SIZE(esccmds); eindex++) {
|
||||||
int i=0, cnt = strnlen(eindex->seq, 4);
|
// n - position in seq to read
|
||||||
|
int i = 0; // position in seq to compare
|
||||||
|
int cnt = strnlen(eindex->seq, 4);
|
||||||
|
|
||||||
// Loop through chars in this sequence.
|
// Loop through chars in this sequence.
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
// We've matched this escape sequence up to [i-1]
|
||||||
// If we've matched this escape sequence so far but need more
|
|
||||||
// chars, read another as long as it wouldn't block. (Note that
|
|
||||||
// escape sequences come in as a unit, so if we would block
|
|
||||||
// it's not really an escape sequence.)
|
|
||||||
if (n <= i) {
|
if (n <= i) {
|
||||||
|
// Need more chars, read another one if it wouldn't block.
|
||||||
|
// (Note that escape sequences come in as a unit,
|
||||||
|
// so if we would block it's not really an escape sequence.)
|
||||||
struct pollfd pfd;
|
struct pollfd pfd;
|
||||||
pfd.fd = 0;
|
pfd.fd = 0;
|
||||||
pfd.events = POLLIN;
|
pfd.events = POLLIN;
|
||||||
if (0 < safe_poll(&pfd, 1, 300)
|
// TODO: what is a good timeout here? why?
|
||||||
&& 0 < safe_read(0, readbuffer + n, 1))
|
if (safe_poll(&pfd, 1, /*timeout:*/ 0)) {
|
||||||
n++;
|
if (safe_read(0, readbuffer + n, 1) <= 0)
|
||||||
|
goto error;
|
||||||
// Since the array is sorted from shortest to longest, if
|
n++;
|
||||||
// we needed more data we can't match anything later, so
|
} else {
|
||||||
// break out of both loops.
|
// No more data!
|
||||||
else goto loop_out;
|
// Array is sorted from shortest to longest,
|
||||||
|
// we can't match anything later in array,
|
||||||
|
// break out of both loops.
|
||||||
|
goto loop_out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (readbuffer[i] != eindex->seq[i]) break;
|
if (readbuffer[i] != eindex->seq[i])
|
||||||
if (++i == cnt) {
|
break; // try next seq
|
||||||
|
if (++i == cnt) { // entire seq matched
|
||||||
c = eindex->val;
|
c = eindex->val;
|
||||||
n = 0;
|
n = 0;
|
||||||
goto loop_out;
|
goto loop_out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// We did not find matching sequence, it was a bare ESC.
|
||||||
|
// We possibly read and stored more input in readbuffer by now.
|
||||||
}
|
}
|
||||||
loop_out:
|
loop_out:
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user