summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--editors/vi.c47
1 files changed, 29 insertions, 18 deletions
diff --git a/editors/vi.c b/editors/vi.c
index a757359..7b213df 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -629,12 +629,12 @@ static void edit_file(char *fn)
}
#endif
do_cmd(c); // execute the user command
- //
+
// poll to see if there is input already waiting. if we are
// not able to display output fast enough to keep up, skip
// the display update until we catch up with input.
- if (mysleep(0) == 0) {
- // no input pending- so update output
+ if (!chars_to_parse && mysleep(0) == 0) {
+ // no input pending - so update output
refresh(FALSE);
show_status_line();
}
@@ -2243,8 +2243,10 @@ static char readit(void) // read (maybe cursor) key from stdin
n = chars_to_parse;
if (n == 0) {
- // If no data, block waiting for input.
- n = safe_read(0, readbuffer, 1);
+ // If no data, block waiting for input
+ // (can't read more than minimal ESC sequence -
+ // see "n = 0" below).
+ n = safe_read(0, readbuffer, 3);
if (n <= 0) {
error:
go_bottom_and_clear_to_eol();
@@ -2264,25 +2266,29 @@ static char readit(void) // read (maybe cursor) key from stdin
// If it's an escape sequence, loop through known matches.
if (c == 27) {
const struct esc_cmds *eindex;
+ struct pollfd pfd;
+ pfd.fd = STDIN_FILENO;
+ pfd.events = POLLIN;
for (eindex = esccmds; eindex < esccmds + ARRAY_SIZE(esccmds); eindex++) {
- // n - position in seq to read
- int i = 0; // position in seq to compare
- int cnt = strnlen(eindex->seq, 4);
+ // n - position in sequence we did not read yet
+ int i = 0; // position in sequence to compare
- // Loop through chars in this sequence.
+ // Loop through chars in this sequence
for (;;) {
- // We've matched this escape sequence up to [i-1]
+ // So far escape sequence matches up to [i-1]
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;
- pfd.fd = 0;
- pfd.events = POLLIN;
- // Timeout is needed to reconnect escape sequences split
- // up by transmission over a serial console.
- if (safe_poll(&pfd, 1, 25)) {
+
+ // Timeout is needed to reconnect escape sequences
+ // split up by transmission over a serial console.
+ // Even though inter-char delay on 1200 baud is <10ms,
+ // process scheduling can enlarge it arbitrarily,
+ // on both send and receive sides.
+ // Erring on the safe side - 5 timer ticks on 100 HZ.
+ if (safe_poll(&pfd, 1, 50)) {
if (safe_read(0, readbuffer + n, 1) <= 0)
goto error;
n++;
@@ -2296,9 +2302,14 @@ static char readit(void) // read (maybe cursor) key from stdin
}
if (readbuffer[i] != eindex->seq[i])
break; // try next seq
- if (++i == cnt) { // entire seq matched
+ i++;
+ if (i == 4 || !eindex->seq[i]) { // entire seq matched
c = eindex->val;
n = 0;
+ // n -= i; memmove(...);
+ // would be more correct,
+ // but we never read ahead that much,
+ // and n == i here.
goto loop_out;
}
}
@@ -2306,7 +2317,7 @@ static char readit(void) // read (maybe cursor) key from stdin
// 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:
chars_to_parse = n;
return c;