nano

nano with my custom patches
git clone git://bsandro.tech/nano
Log | Files | Refs | README | LICENSE

commit 2c8c061e672435edbfef0c9737972ecd2a231ee4
parent 5fab1e675410faaf88fcee0d6c80818c9d56966a
Author: Benno Schulenberg <bensberg@telfort.nl>
Date:   Sat,  8 Aug 2020 19:01:34 +0200

tweaks: pass first byte of sequence directly to the decoding function

Don't bother stuffing it back into the keyboard buffer when it will be
taken out again straight afterward.

Diffstat:
Msrc/winio.c | 205+++++++++++++++++++++++++++++++++++++++----------------------------------------
1 file changed, 101 insertions(+), 104 deletions(-)

diff --git a/src/winio.c b/src/winio.c @@ -332,28 +332,28 @@ int arrow_from_ABCD(int letter) * keypad values, into their corresponding key values. These sequences * are generated when the keypad doesn't support the needed keys. * Assume that Escape has already been read in. */ -int convert_sequence(const int *seq, size_t length, int *consumed) +int convert_sequence(int first, const int *seq, size_t length, int *consumed) { - *consumed = 2; + *consumed = 1; - if (seq[0] == 'O') { - switch (seq[1]) { + if (first == 'O') { + switch (seq[0]) { case '1': - if (length > 4 && seq[2] == ';') { - *consumed = 5; - switch (seq[3]) { + if (length > 3 && seq[1] == ';') { + *consumed = 4; + switch (seq[2]) { case '2': - switch (seq[4]) { + switch (seq[3]) { case 'A': /* Esc O 1 ; 2 A == Shift-Up on Terminal. */ case 'B': /* Esc O 1 ; 2 B == Shift-Down on Terminal. */ case 'C': /* Esc O 1 ; 2 C == Shift-Right on Terminal. */ case 'D': /* Esc O 1 ; 2 D == Shift-Left on Terminal. */ shift_held = TRUE; - return arrow_from_ABCD(seq[4]); + return arrow_from_ABCD(seq[3]); } break; case '5': - switch (seq[4]) { + switch (seq[3]) { case 'A': /* Esc O 1 ; 5 A == Ctrl-Up on Terminal. */ return CONTROL_UP; case 'B': /* Esc O 1 ; 5 B == Ctrl-Down on Terminal. */ @@ -374,13 +374,13 @@ int convert_sequence(const int *seq, size_t length, int *consumed) case '6': /* Shift+Ctrl */ case '7': /* Alt+Ctrl */ case '8': /* Shift+Alt+Ctrl */ - if (length > 2) { - *consumed = 3; + if (length > 1) { + *consumed = 2; /* Do not accept multiple modifiers. */ - if (seq[1] == '4' || seq[1] > '5') + if (seq[0] == '4' || seq[0] > '5') return FOREIGN_SEQUENCE; #ifndef NANO_TINY - switch (seq[2]) { + switch (seq[1]) { case 'A': /* Esc O 5 A == Ctrl-Up on Haiku. */ return CONTROL_UP; case 'B': /* Esc O 5 B == Ctrl-Down on Haiku. */ @@ -394,14 +394,14 @@ int convert_sequence(const int *seq, size_t length, int *consumed) /* Translate Shift+digit on the keypad to the digit * (Esc O 2 p == Shift-0, ...), modifier+operator to * the operator, and modifier+Enter to CR. */ - return (seq[2] - 0x40); + return (seq[1] - 0x40); } break; case 'A': /* Esc O A == Up on VT100/VT320. */ case 'B': /* Esc O B == Down on VT100/VT320. */ case 'C': /* Esc O C == Right on VT100/VT320. */ case 'D': /* Esc O D == Left on VT100/VT320. */ - return arrow_from_ABCD(seq[1]); + return arrow_from_ABCD(seq[0]); case 'F': /* Esc O F == End on old xterm. */ return KEY_END; case 'H': /* Esc O H == Home on old xterm. */ @@ -419,7 +419,7 @@ int convert_sequence(const int *seq, size_t length, int *consumed) case 'W': /* Esc O W == F8 on Mach console. */ case 'X': /* Esc O X == F9 on Mach console. */ case 'Y': /* Esc O Y == F10 on Mach console. */ - return KEY_F(seq[1] - 'O'); + return KEY_F(seq[0] - 'O'); case 'a': /* Esc O a == Ctrl-Up on rxvt/Eterm. */ return CONTROL_UP; case 'b': /* Esc O b == Ctrl-Down on rxvt/Eterm. */ @@ -464,41 +464,41 @@ int convert_sequence(const int *seq, size_t length, int *consumed) case 'y': /* Esc O y == PageUp (9) on the same. */ return KEY_PPAGE; } - } else if (seq[0] == '[') { - if (seq[1] < '9') - *consumed = 3; - switch (seq[1]) { + } else if (first == '[') { + if (seq[0] < '9') + *consumed = 2; + switch (seq[0]) { case '1': - if (length > 2 && seq[2] == '~') + if (length > 1 && seq[1] == '~') /* Esc [ 1 ~ == Home on VT320/Linux console. */ return KEY_HOME; - else if (length > 3 && seq[3] == '~') { - *consumed = 4; - switch (seq[2]) { + else if (length > 2 && seq[2] == '~') { + *consumed = 3; + switch (seq[1]) { case '1': /* Esc [ 1 1 ~ == F1 on rxvt/Eterm. */ case '2': /* Esc [ 1 2 ~ == F2 on rxvt/Eterm. */ case '3': /* Esc [ 1 3 ~ == F3 on rxvt/Eterm. */ case '4': /* Esc [ 1 4 ~ == F4 on rxvt/Eterm. */ case '5': /* Esc [ 1 5 ~ == F5 on xterm/rxvt/Eterm. */ - return KEY_F(seq[2] - '0'); + return KEY_F(seq[1] - '0'); case '7': /* Esc [ 1 7 ~ == F6 on VT220/VT320/ * Linux console/xterm/rxvt/Eterm. */ case '8': /* Esc [ 1 8 ~ == F7 on the same. */ case '9': /* Esc [ 1 9 ~ == F8 on the same. */ - return KEY_F(seq[2] - '1'); + return KEY_F(seq[1] - '1'); } - } else if (length > 4 && seq[2] == ';') { + } else if (length > 3 && seq[1] == ';') { /* <-<-<-<-<-<-<- */ - *consumed = 5; - switch (seq[3]) { + *consumed = 4; + switch (seq[2]) { case '2': - switch (seq[4]) { + switch (seq[3]) { case 'A': /* Esc [ 1 ; 2 A == Shift-Up on xterm. */ case 'B': /* Esc [ 1 ; 2 B == Shift-Down on xterm. */ case 'C': /* Esc [ 1 ; 2 C == Shift-Right on xterm. */ case 'D': /* Esc [ 1 ; 2 D == Shift-Left on xterm. */ shift_held = TRUE; - return arrow_from_ABCD(seq[4]); + return arrow_from_ABCD(seq[3]); #ifndef NANO_TINY case 'F': /* Esc [ 1 ; 2 F == Shift-End on xterm. */ return SHIFT_END; @@ -510,7 +510,7 @@ int convert_sequence(const int *seq, size_t length, int *consumed) #ifndef NANO_TINY case '9': /* To accommodate iTerm2 in "xterm mode". */ case '3': - switch (seq[4]) { + switch (seq[3]) { case 'A': /* Esc [ 1 ; 3 A == Alt-Up on xterm. */ return ALT_UP; case 'B': /* Esc [ 1 ; 3 B == Alt-Down on xterm. */ @@ -524,7 +524,7 @@ int convert_sequence(const int *seq, size_t length, int *consumed) case '4': /* When the arrow keys are held together with Shift+Meta, * act as if they are Home/End/PgUp/PgDown with Shift. */ - switch (seq[4]) { + switch (seq[3]) { case 'A': /* Esc [ 1 ; 4 A == Shift-Alt-Up on xterm. */ return SHIFT_PAGEUP; case 'B': /* Esc [ 1 ; 4 B == Shift-Alt-Down on xterm. */ @@ -537,7 +537,7 @@ int convert_sequence(const int *seq, size_t length, int *consumed) break; #endif case '5': - switch (seq[4]) { + switch (seq[3]) { case 'A': /* Esc [ 1 ; 5 A == Ctrl-Up on xterm. */ return CONTROL_UP; case 'B': /* Esc [ 1 ; 5 B == Ctrl-Down on xterm. */ @@ -554,7 +554,7 @@ int convert_sequence(const int *seq, size_t length, int *consumed) break; #ifndef NANO_TINY case '6': - switch (seq[4]) { + switch (seq[3]) { case 'A': /* Esc [ 1 ; 6 A == Shift-Ctrl-Up on xterm. */ return shiftcontrolup; case 'B': /* Esc [ 1 ; 6 B == Shift-Ctrl-Down on xterm. */ @@ -572,19 +572,19 @@ int convert_sequence(const int *seq, size_t length, int *consumed) #endif } /* ->->->->->->-> */ - } else if (length > 5 && seq[3] == ';' && seq[5] == '~') + } else if (length > 4 && seq[2] == ';' && seq[4] == '~') /* Esc [ 1 n ; 2 ~ == F17...F20 on some terminals. */ - *consumed = 6; + *consumed = 5; #ifdef USE_SLANG - else if (length == 4 && seq[3] == ';') + else if (length == 3 && seq[2] == ';') /* Discard broken sequences that Slang produces. */ - *consumed = 4; + *consumed = 3; #endif break; case '2': - if (length > 3 && seq[3] == '~') { - *consumed = 4; - switch (seq[2]) { + if (length > 2 && seq[2] == '~') { + *consumed = 3; + switch (seq[1]) { case '0': /* Esc [ 2 0 ~ == F9 on VT220/VT320/ * Linux console/xterm/rxvt/Eterm. */ return KEY_F(9); @@ -595,35 +595,35 @@ int convert_sequence(const int *seq, size_t length, int *consumed) case '4': /* Esc [ 2 4 ~ == F12 on the same. */ return KEY_F(12); } - } else if (length > 2 && seq[2] == '~') + } else if (length > 1 && seq[1] == '~') /* Esc [ 2 ~ == Insert on VT220/VT320/ * Linux console/xterm/Terminal. */ return KEY_IC; - else if (length > 4 && seq[2] == ';' && seq[4] == '~') { + else if (length > 3 && seq[1] == ';' && seq[3] == '~') { /* Esc [ 2 ; x ~ == modified Insert on xterm. */ - *consumed = 5; + *consumed = 4; #ifndef NANO_TINY - if (seq[3] == '3') + if (seq[2] == '3') return ALT_INSERT; #endif } - else if (length > 5 && seq[3] == ';' && seq[5] == '~') + else if (length > 4 && seq[2] == ';' && seq[4] == '~') /* Esc [ 2 n ; 2 ~ == F21...F24 on some terminals. */ - *consumed = 6; + *consumed = 5; #ifdef USE_SLANG - else if (length == 4 && seq[3] == ';') + else if (length == 3 && seq[2] == ';') /* Discard broken sequences that Slang produces. */ - *consumed = 4; + *consumed = 3; #endif #ifndef NANO_TINY - else if (length > 4 && seq[2] == '0' && seq[4] == '~') { + else if (length > 3 && seq[1] == '0' && seq[3] == '~') { /* Esc [ 2 0 0 ~ == start of a bracketed paste, * Esc [ 2 0 1 ~ == end of a bracketed paste. */ - *consumed = 5; - if (seq[3] == '0') { + *consumed = 4; + if (seq[2] == '0') { bracketed_paste = TRUE; return BRACKETED_PASTE_MARKER; - } else if (seq[3] == '1') { + } else if (seq[2] == '1') { bracketed_paste = FALSE; return BRACKETED_PASTE_MARKER; } @@ -632,69 +632,69 @@ int convert_sequence(const int *seq, size_t length, int *consumed) break; case '3': /* Esc [ 3 ~ == Delete on VT220/VT320/ * Linux console/xterm/Terminal. */ - if (length > 2 && seq[2] == '~') + if (length > 1 && seq[1] == '~') return KEY_DC; - if (length > 4 && seq[2] == ';' && seq[4] == '~') { - *consumed = 5; + if (length > 3 && seq[1] == ';' && seq[3] == '~') { + *consumed = 4; #ifndef NANO_TINY - if (seq[3] == '2') + if (seq[2] == '2') /* Esc [ 3 ; 2 ~ == Shift-Delete on xterm/Terminal. */ return SHIFT_DELETE; - if (seq[3] == '3') + if (seq[2] == '3') /* Esc [ 3 ; 3 ~ == Alt-Delete on xterm/rxvt/Eterm/Terminal. */ return ALT_DELETE; - if (seq[3] == '5') + if (seq[2] == '5') /* Esc [ 3 ; 5 ~ == Ctrl-Delete on xterm. */ return CONTROL_DELETE; - if (seq[3] == '6') + if (seq[2] == '6') /* Esc [ 3 ; 6 ~ == Ctrl-Shift-Delete on xterm. */ return controlshiftdelete; #endif } #ifndef NANO_TINY - if (length > 2 && seq[2] == '$') + if (length > 1 && seq[1] == '$') /* Esc [ 3 $ == Shift-Delete on urxvt. */ return SHIFT_DELETE; - if (length > 2 && seq[2] == '^') + if (length > 1 && seq[1] == '^') /* Esc [ 3 ^ == Ctrl-Delete on urxvt. */ return CONTROL_DELETE; - if (length > 2 && seq[2] == '@') + if (length > 1 && seq[1] == '@') /* Esc [ 3 @ == Ctrl-Shift-Delete on urxvt. */ return controlshiftdelete; - if (length > 3 && seq[3] == '~') + if (length > 2 && seq[2] == '~') /* Esc [ 3 n ~ == F17...F20 on some terminals. */ - *consumed = 4; + *consumed = 3; #endif break; case '4': /* Esc [ 4 ~ == End on VT220/VT320/ * Linux console/xterm. */ - if (length > 2 && seq[2] == '~') + if (length > 1 && seq[1] == '~') return KEY_END; break; case '5': /* Esc [ 5 ~ == PageUp on VT220/VT320/ * Linux console/xterm/Eterm/urxvt/Terminal */ - if (length > 2 && seq[2] == '~') + if (length > 1 && seq[1] == '~') return KEY_PPAGE; - else if (length > 4 && seq[2] == ';' && seq[4] == '~') { - *consumed = 5; + else if (length > 3 && seq[1] == ';' && seq[3] == '~') { + *consumed = 4; #ifndef NANO_TINY - if (seq[3] == '2') + if (seq[2] == '2') return shiftaltup; - if (seq[3] == '3') + if (seq[2] == '3') return ALT_PAGEUP; #endif } break; case '6': /* Esc [ 6 ~ == PageDown on VT220/VT320/ * Linux console/xterm/Eterm/urxvt/Terminal */ - if (length > 2 && seq[2] == '~') + if (length > 1 && seq[1] == '~') return KEY_NPAGE; - else if (length > 4 && seq[2] == ';' && seq[4] == '~') { - *consumed = 5; + else if (length > 3 && seq[1] == ';' && seq[3] == '~') { + *consumed = 4; #ifndef NANO_TINY - if (seq[3] == '2') + if (seq[2] == '2') return shiftaltdown; - if (seq[3] == '3') + if (seq[2] == '3') return ALT_PAGEDOWN; #endif } @@ -703,14 +703,14 @@ int convert_sequence(const int *seq, size_t length, int *consumed) * Esc [ 7 $ == Shift-Home on Eterm/rxvt; * Esc [ 7 ^ == Control-Home on Eterm/rxvt; * Esc [ 7 @ == Shift-Control-Home on same. */ - if (length > 2 && seq[2] == '~') + if (length > 1 && seq[1] == '~') return KEY_HOME; - else if (length > 2 && seq[2] == '$') + else if (length > 1 && seq[1] == '$') return SHIFT_HOME; - else if (length > 2 && seq[2] == '^') + else if (length > 1 && seq[1] == '^') return CONTROL_HOME; #ifndef NANO_TINY - else if (length > 2 && seq[2] == '@') + else if (length > 1 && seq[1] == '@') return shiftcontrolhome; #endif break; @@ -718,14 +718,14 @@ int convert_sequence(const int *seq, size_t length, int *consumed) * Esc [ 8 $ == Shift-End on Eterm/rxvt; * Esc [ 8 ^ == Control-End on Eterm/rxvt; * Esc [ 8 @ == Shift-Control-End on same. */ - if (length > 2 && seq[2] == '~') + if (length > 1 && seq[1] == '~') return KEY_END; - else if (length > 2 && seq[2] == '$') + else if (length > 1 && seq[1] == '$') return SHIFT_END; - else if (length > 2 && seq[2] == '^') + else if (length > 1 && seq[1] == '^') return CONTROL_END; #ifndef NANO_TINY - else if (length > 2 && seq[2] == '@') + else if (length > 1 && seq[1] == '@') return shiftcontrolend; #endif break; @@ -739,7 +739,7 @@ int convert_sequence(const int *seq, size_t length, int *consumed) case 'B': /* Esc [ B == Down on the same. */ case 'C': /* Esc [ C == Right on the same. */ case 'D': /* Esc [ D == Left on the same. */ - return arrow_from_ABCD(seq[1]); + return arrow_from_ABCD(seq[0]); case 'F': /* Esc [ F == End on FreeBSD console/Eterm. */ return KEY_END; case 'G': /* Esc [ G == PageDown on FreeBSD console. */ @@ -756,14 +756,14 @@ int convert_sequence(const int *seq, size_t length, int *consumed) case 'N': /* Esc [ N == F2 on FreeBSD console. */ return KEY_F(2); case 'O': - if (length > 2) { - *consumed = 3; - if ('O' < seq[2] && seq[2] < 'T') + if (length > 1) { + *consumed = 2; + if ('O' < seq[1] && seq[1] < 'T') /* Esc [ O P == F1 on xterm. */ /* Esc [ O Q == F2 on xterm. */ /* Esc [ O R == F3 on xterm. */ /* Esc [ O S == F4 on xterm. */ - return KEY_F(seq[2] - 'O'); + return KEY_F(seq[1] - 'O'); } else /* Esc [ O == F3 on FreeBSD console. */ return KEY_F(3); @@ -773,7 +773,7 @@ int convert_sequence(const int *seq, size_t length, int *consumed) case 'R': /* Esc [ R == F6 on FreeBSD console. */ case 'S': /* Esc [ S == F7 on FreeBSD console. */ case 'T': /* Esc [ T == F8 on FreeBSD console. */ - return KEY_F(4 + seq[1] - 'P'); + return KEY_F(4 + seq[0] - 'P'); case 'U': /* Esc [ U == PageDown on Mach console. */ return KEY_NPAGE; case 'V': /* Esc [ V == PageUp on Mach console. */ @@ -792,17 +792,17 @@ int convert_sequence(const int *seq, size_t length, int *consumed) case 'c': /* Esc [ c == Shift-Right on rxvt/Eterm. */ case 'd': /* Esc [ d == Shift-Left on rxvt/Eterm. */ shift_held = TRUE; - return arrow_from_ABCD(seq[1] - 0x20); + return arrow_from_ABCD(seq[0] - 0x20); case '[': - if (length > 2) { - *consumed = 3; - if ('@' < seq[2] && seq[2] < 'F') + if (length > 1) { + *consumed = 2; + if ('@' < seq[1] && seq[1] < 'F') /* Esc [ [ A == F1 on Linux console. */ /* Esc [ [ B == F2 on Linux console. */ /* Esc [ [ C == F3 on Linux console. */ /* Esc [ [ D == F4 on Linux console. */ /* Esc [ [ E == F5 on Linux console. */ - return KEY_F(seq[2] - '@'); + return KEY_F(seq[1] - '@'); } break; } @@ -818,15 +818,12 @@ int parse_escape_sequence(int firstbyte) { int *sequence, length, consumed, keycode; - /* Put the first character of the sequence back into the keybuffer. */ - put_back(firstbyte); - - /* Grab at most six integers (the longest possible escape sequence) - * from the keybuffer. */ - length = (key_buffer_len < 6 ? key_buffer_len : 6); + /* Grab at most five integers (the longest possible escape sequence + * minus its first element) from the keybuffer. */ + length = (key_buffer_len < 5 ? key_buffer_len : 5); sequence = get_input(NULL, length); - keycode = convert_sequence(sequence, length, &consumed); + keycode = convert_sequence(firstbyte, sequence, length, &consumed); /* If not all grabbed integers were consumed, put the leftovers back. */ for (int i = length - 1; i >= consumed; i--)