From 12fe0a3b29df6335f77c0ca8760b912ff43d9515 Mon Sep 17 00:00:00 2001 From: Benno Schulenberg Date: Sat, 8 Aug 2020 19:44:54 +0200 Subject: [PATCH] tweaks: normalize the indentation after the previous change This finally gets rid of the piece of specially reduced indentation (<-<- ... ->->) that made it hard to see the structure of the code. --- src/winio.c | 924 ++++++++++++++++++++++++++-------------------------- 1 file changed, 461 insertions(+), 463 deletions(-) diff --git a/src/winio.c b/src/winio.c index e2162f45..f6afa1d2 100644 --- a/src/winio.c +++ b/src/winio.c @@ -331,133 +331,133 @@ int arrow_from_ABCD(int letter) /* Translate a sequence that began with "Esc O" to its corresponding key code. */ int convert_SS3_sequence(const int *seq, size_t length, int *consumed) { - switch (seq[0]) { - case '1': - if (length > 3 && seq[1] == ';') { - *consumed = 4; - switch (seq[2]) { - case '2': - 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[3]); - } - break; - case '5': - 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. */ - return CONTROL_DOWN; - case 'C': /* Esc O 1 ; 5 C == Ctrl-Right on Terminal. */ - return CONTROL_RIGHT; - case 'D': /* Esc O 1 ; 5 D == Ctrl-Left on Terminal. */ - return CONTROL_LEFT; - } - break; - } + switch (seq[0]) { + case '1': + if (length > 3 && seq[1] == ';') { + *consumed = 4; + switch (seq[2]) { + case '2': + 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[3]); + } + break; + case '5': + 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. */ + return CONTROL_DOWN; + case 'C': /* Esc O 1 ; 5 C == Ctrl-Right on Terminal. */ + return CONTROL_RIGHT; + case 'D': /* Esc O 1 ; 5 D == Ctrl-Left on Terminal. */ + return CONTROL_LEFT; + } + break; } - break; - case '2': /* Shift */ - case '3': /* Alt */ - case '4': /* Shift+Alt */ - case '5': /* Ctrl */ - case '6': /* Shift+Ctrl */ - case '7': /* Alt+Ctrl */ - case '8': /* Shift+Alt+Ctrl */ - if (length > 1) { - *consumed = 2; - /* Do not accept multiple modifiers. */ - if (seq[0] == '4' || seq[0] > '5') - return FOREIGN_SEQUENCE; + } + break; + case '2': /* Shift */ + case '3': /* Alt */ + case '4': /* Shift+Alt */ + case '5': /* Ctrl */ + case '6': /* Shift+Ctrl */ + case '7': /* Alt+Ctrl */ + case '8': /* Shift+Alt+Ctrl */ + if (length > 1) { + *consumed = 2; + /* Do not accept multiple modifiers. */ + if (seq[0] == '4' || seq[0] > '5') + return FOREIGN_SEQUENCE; #ifndef NANO_TINY - 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. */ - return CONTROL_DOWN; - case 'C': /* Esc O 5 C == Ctrl-Right on Haiku. */ - return CONTROL_RIGHT; - case 'D': /* Esc O 5 D == Ctrl-Left on Haiku. */ - return CONTROL_LEFT; - } -#endif - /* 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[1] - 0x40); + 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. */ + return CONTROL_DOWN; + case 'C': /* Esc O 5 C == Ctrl-Right on Haiku. */ + return CONTROL_RIGHT; + case 'D': /* Esc O 5 D == Ctrl-Left on Haiku. */ + return CONTROL_LEFT; } - 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[0]); - case 'F': /* Esc O F == End on old xterm. */ - return KEY_END; - case 'H': /* Esc O H == Home on old xterm. */ - return KEY_HOME; - case 'M': /* Esc O M == Enter on numeric keypad - * with NumLock off on VT100/VT220/VT320. */ - return KEY_ENTER; - case 'P': /* Esc O P == F1 on VT100/VT220/VT320/Mach console. */ - case 'Q': /* Esc O Q == F2 on VT100/VT220/VT320/Mach console. */ - case 'R': /* Esc O R == F3 on VT100/VT220/VT320/Mach console. */ - case 'S': /* Esc O S == F4 on VT100/VT220/VT320/Mach console. */ - case 'T': /* Esc O T == F5 on Mach console. */ - case 'U': /* Esc O U == F6 on Mach console. */ - case 'V': /* Esc O V == F7 on Mach console. */ - 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[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. */ - return CONTROL_DOWN; - case 'c': /* Esc O c == Ctrl-Right on rxvt/Eterm. */ - return CONTROL_RIGHT; - case 'd': /* Esc O d == Ctrl-Left on rxvt/Eterm. */ - return CONTROL_LEFT; - case 'j': /* Esc O j == '*' on numeric keypad with - * NumLock off on xterm/rxvt/Eterm. */ - return '*'; - case 'k': /* Esc O k == '+' on the same. */ - return '+'; - case 'l': /* Esc O l == ',' on VT100/VT220/VT320. */ - return ','; - case 'm': /* Esc O m == '-' on numeric keypad with - * NumLock off on VTnnn/xterm/rxvt/Eterm. */ - return '-'; - case 'n': /* Esc O n == Delete (.) on numeric keypad - * with NumLock off on rxvt/Eterm. */ - return KEY_DC; - case 'o': /* Esc O o == '/' on numeric keypad with - * NumLock off on VTnnn/xterm/rxvt/Eterm. */ - return '/'; - case 'p': /* Esc O p == Insert (0) on numeric keypad - * with NumLock off on rxvt/Eterm. */ - return KEY_IC; - case 'q': /* Esc O q == End (1) on the same. */ - return KEY_END; - case 'r': /* Esc O r == Down (2) on the same. */ - return KEY_DOWN; - case 's': /* Esc O s == PageDown (3) on the same. */ - return KEY_NPAGE; - case 't': /* Esc O t == Left (4) on the same. */ - return KEY_LEFT; - case 'v': /* Esc O v == Right (6) on the same. */ - return KEY_RIGHT; - case 'w': /* Esc O w == Home (7) on the same. */ - return KEY_HOME; - case 'x': /* Esc O x == Up (8) on the same. */ - return KEY_UP; - case 'y': /* Esc O y == PageUp (9) on the same. */ - return KEY_PPAGE; - } +#endif + /* 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[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[0]); + case 'F': /* Esc O F == End on old xterm. */ + return KEY_END; + case 'H': /* Esc O H == Home on old xterm. */ + return KEY_HOME; + case 'M': /* Esc O M == Enter on numeric keypad + * with NumLock off on VT100/VT220/VT320. */ + return KEY_ENTER; + case 'P': /* Esc O P == F1 on VT100/VT220/VT320/Mach console. */ + case 'Q': /* Esc O Q == F2 on VT100/VT220/VT320/Mach console. */ + case 'R': /* Esc O R == F3 on VT100/VT220/VT320/Mach console. */ + case 'S': /* Esc O S == F4 on VT100/VT220/VT320/Mach console. */ + case 'T': /* Esc O T == F5 on Mach console. */ + case 'U': /* Esc O U == F6 on Mach console. */ + case 'V': /* Esc O V == F7 on Mach console. */ + 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[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. */ + return CONTROL_DOWN; + case 'c': /* Esc O c == Ctrl-Right on rxvt/Eterm. */ + return CONTROL_RIGHT; + case 'd': /* Esc O d == Ctrl-Left on rxvt/Eterm. */ + return CONTROL_LEFT; + case 'j': /* Esc O j == '*' on numeric keypad with + * NumLock off on xterm/rxvt/Eterm. */ + return '*'; + case 'k': /* Esc O k == '+' on the same. */ + return '+'; + case 'l': /* Esc O l == ',' on VT100/VT220/VT320. */ + return ','; + case 'm': /* Esc O m == '-' on numeric keypad with + * NumLock off on VTnnn/xterm/rxvt/Eterm. */ + return '-'; + case 'n': /* Esc O n == Delete (.) on numeric keypad + * with NumLock off on rxvt/Eterm. */ + return KEY_DC; + case 'o': /* Esc O o == '/' on numeric keypad with + * NumLock off on VTnnn/xterm/rxvt/Eterm. */ + return '/'; + case 'p': /* Esc O p == Insert (0) on numeric keypad + * with NumLock off on rxvt/Eterm. */ + return KEY_IC; + case 'q': /* Esc O q == End (1) on the same. */ + return KEY_END; + case 'r': /* Esc O r == Down (2) on the same. */ + return KEY_DOWN; + case 's': /* Esc O s == PageDown (3) on the same. */ + return KEY_NPAGE; + case 't': /* Esc O t == Left (4) on the same. */ + return KEY_LEFT; + case 'v': /* Esc O v == Right (6) on the same. */ + return KEY_RIGHT; + case 'w': /* Esc O w == Home (7) on the same. */ + return KEY_HOME; + case 'x': /* Esc O x == Up (8) on the same. */ + return KEY_UP; + case 'y': /* Esc O y == PageUp (9) on the same. */ + return KEY_PPAGE; + } return FOREIGN_SEQUENCE; } @@ -465,347 +465,345 @@ int convert_SS3_sequence(const int *seq, size_t length, int *consumed) /* Translate a sequence that began with "Esc [" to its corresponding key code. */ int convert_CSI_sequence(const int *seq, size_t length, int *consumed) { - if (seq[0] < '9') - *consumed = 2; - switch (seq[0]) { - case '1': - if (length > 1 && seq[1] == '~') - /* Esc [ 1 ~ == Home on VT320/Linux console. */ - return KEY_HOME; - 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[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[1] - '1'); - } - } else if (length > 3 && seq[1] == ';') { - /* <-<-<-<-<-<-<- */ - *consumed = 4; - switch (seq[2]) { - case '2': - 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[3]); -#ifndef NANO_TINY - case 'F': /* Esc [ 1 ; 2 F == Shift-End on xterm. */ - return SHIFT_END; - case 'H': /* Esc [ 1 ; 2 H == Shift-Home on xterm. */ - return SHIFT_HOME; -#endif - } - break; -#ifndef NANO_TINY - case '9': /* To accommodate iTerm2 in "xterm mode". */ - case '3': - 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. */ - return ALT_DOWN; - case 'C': /* Esc [ 1 ; 3 C == Alt-Right on xterm. */ - return ALT_RIGHT; - case 'D': /* Esc [ 1 ; 3 D == Alt-Left on xterm. */ - return ALT_LEFT; - } - break; - 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[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. */ - return SHIFT_PAGEDOWN; - case 'C': /* Esc [ 1 ; 4 C == Shift-Alt-Right on xterm. */ - return SHIFT_END; - case 'D': /* Esc [ 1 ; 4 D == Shift-Alt-Left on xterm. */ - return SHIFT_HOME; - } - break; -#endif - case '5': - 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. */ - return CONTROL_DOWN; - case 'C': /* Esc [ 1 ; 5 C == Ctrl-Right on xterm. */ - return CONTROL_RIGHT; - case 'D': /* Esc [ 1 ; 5 D == Ctrl-Left on xterm. */ - return CONTROL_LEFT; - case 'F': /* Esc [ 1 ; 5 F == Ctrl-End on xterm. */ - return CONTROL_END; - case 'H': /* Esc [ 1 ; 5 H == Ctrl-Home on xterm. */ - return CONTROL_HOME; - } - break; -#ifndef NANO_TINY - case '6': - 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. */ - return shiftcontroldown; - case 'C': /* Esc [ 1 ; 6 C == Shift-Ctrl-Right on xterm. */ - return shiftcontrolright; - case 'D': /* Esc [ 1 ; 6 D == Shift-Ctrl-Left on xterm. */ - return shiftcontrolleft; - case 'F': /* Esc [ 1 ; 6 F == Shift-Ctrl-End on xterm. */ - return shiftcontrolend; - case 'H': /* Esc [ 1 ; 6 H == Shift-Ctrl-Home on xterm. */ - return shiftcontrolhome; - } - break; -#endif - } - /* ->->->->->->-> */ - } else if (length > 4 && seq[2] == ';' && seq[4] == '~') - /* Esc [ 1 n ; 2 ~ == F17...F20 on some terminals. */ - *consumed = 5; -#ifdef USE_SLANG - else if (length == 3 && seq[2] == ';') - /* Discard broken sequences that Slang produces. */ - *consumed = 3; -#endif - break; - case '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); - case '1': /* Esc [ 2 1 ~ == F10 on the same. */ - return KEY_F(10); - case '3': /* Esc [ 2 3 ~ == F11 on the same. */ - return KEY_F(11); - case '4': /* Esc [ 2 4 ~ == F12 on the same. */ - return KEY_F(12); - } - } else if (length > 1 && seq[1] == '~') - /* Esc [ 2 ~ == Insert on VT220/VT320/ - * Linux console/xterm/Terminal. */ - return KEY_IC; - else if (length > 3 && seq[1] == ';' && seq[3] == '~') { - /* Esc [ 2 ; x ~ == modified Insert on xterm. */ - *consumed = 4; -#ifndef NANO_TINY - if (seq[2] == '3') - return ALT_INSERT; -#endif - } - else if (length > 4 && seq[2] == ';' && seq[4] == '~') - /* Esc [ 2 n ; 2 ~ == F21...F24 on some terminals. */ - *consumed = 5; -#ifdef USE_SLANG - else if (length == 3 && seq[2] == ';') - /* Discard broken sequences that Slang produces. */ - *consumed = 3; -#endif -#ifndef NANO_TINY - 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 = 4; - if (seq[2] == '0') { - bracketed_paste = TRUE; - return BRACKETED_PASTE_MARKER; - } else if (seq[2] == '1') { - bracketed_paste = FALSE; - return BRACKETED_PASTE_MARKER; - } - } -#endif - break; - case '3': /* Esc [ 3 ~ == Delete on VT220/VT320/ - * Linux console/xterm/Terminal. */ - if (length > 1 && seq[1] == '~') - return KEY_DC; - if (length > 3 && seq[1] == ';' && seq[3] == '~') { - *consumed = 4; -#ifndef NANO_TINY - if (seq[2] == '2') - /* Esc [ 3 ; 2 ~ == Shift-Delete on xterm/Terminal. */ - return SHIFT_DELETE; - if (seq[2] == '3') - /* Esc [ 3 ; 3 ~ == Alt-Delete on xterm/rxvt/Eterm/Terminal. */ - return ALT_DELETE; - if (seq[2] == '5') - /* Esc [ 3 ; 5 ~ == Ctrl-Delete on xterm. */ - return CONTROL_DELETE; - if (seq[2] == '6') - /* Esc [ 3 ; 6 ~ == Ctrl-Shift-Delete on xterm. */ - return controlshiftdelete; -#endif - } -#ifndef NANO_TINY - if (length > 1 && seq[1] == '$') - /* Esc [ 3 $ == Shift-Delete on urxvt. */ - return SHIFT_DELETE; - if (length > 1 && seq[1] == '^') - /* Esc [ 3 ^ == Ctrl-Delete on urxvt. */ - return CONTROL_DELETE; - if (length > 1 && seq[1] == '@') - /* Esc [ 3 @ == Ctrl-Shift-Delete on urxvt. */ - return controlshiftdelete; - if (length > 2 && seq[2] == '~') - /* Esc [ 3 n ~ == F17...F20 on some terminals. */ - *consumed = 3; -#endif - break; - case '4': /* Esc [ 4 ~ == End on VT220/VT320/ - * Linux console/xterm. */ - 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 > 1 && seq[1] == '~') - return KEY_PPAGE; - else if (length > 3 && seq[1] == ';' && seq[3] == '~') { - *consumed = 4; -#ifndef NANO_TINY - if (seq[2] == '2') - return shiftaltup; - 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 > 1 && seq[1] == '~') - return KEY_NPAGE; - else if (length > 3 && seq[1] == ';' && seq[3] == '~') { - *consumed = 4; -#ifndef NANO_TINY - if (seq[2] == '2') - return shiftaltdown; - if (seq[2] == '3') - return ALT_PAGEDOWN; -#endif - } - break; - case '7': /* Esc [ 7 ~ == Home on Eterm/rxvt; - * Esc [ 7 $ == Shift-Home on Eterm/rxvt; - * Esc [ 7 ^ == Control-Home on Eterm/rxvt; - * Esc [ 7 @ == Shift-Control-Home on same. */ - if (length > 1 && seq[1] == '~') - return KEY_HOME; - else if (length > 1 && seq[1] == '$') - return SHIFT_HOME; - else if (length > 1 && seq[1] == '^') - return CONTROL_HOME; -#ifndef NANO_TINY - else if (length > 1 && seq[1] == '@') - return shiftcontrolhome; -#endif - break; - case '8': /* Esc [ 8 ~ == End on Eterm/rxvt; - * Esc [ 8 $ == Shift-End on Eterm/rxvt; - * Esc [ 8 ^ == Control-End on Eterm/rxvt; - * Esc [ 8 @ == Shift-Control-End on same. */ - if (length > 1 && seq[1] == '~') - return KEY_END; - else if (length > 1 && seq[1] == '$') - return SHIFT_END; - else if (length > 1 && seq[1] == '^') - return CONTROL_END; -#ifndef NANO_TINY - else if (length > 1 && seq[1] == '@') - return shiftcontrolend; -#endif - break; - case '9': /* Esc [ 9 == Delete on Mach console. */ - return KEY_DC; - case '@': /* Esc [ @ == Insert on Mach console. */ - return KEY_IC; - case 'A': /* Esc [ A == Up on ANSI/VT220/Linux console/ - * FreeBSD console/Mach console/xterm/Eterm/ - * urxvt/Gnome and Xfce Terminal. */ - 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[0]); - case 'F': /* Esc [ F == End on FreeBSD console/Eterm. */ - return KEY_END; - case 'G': /* Esc [ G == PageDown on FreeBSD console. */ - return KEY_NPAGE; - case 'H': /* Esc [ H == Home on ANSI/VT220/FreeBSD - * console/Mach console/Eterm. */ + if (seq[0] < '9') + *consumed = 2; + switch (seq[0]) { + case '1': + if (length > 1 && seq[1] == '~') + /* Esc [ 1 ~ == Home on VT320/Linux console. */ return KEY_HOME; - case 'I': /* Esc [ I == PageUp on FreeBSD console. */ - return KEY_PPAGE; - case 'L': /* Esc [ L == Insert on ANSI/FreeBSD console. */ - return KEY_IC; - case 'M': /* Esc [ M == F1 on FreeBSD console. */ - return KEY_F(1); - case 'N': /* Esc [ N == F2 on FreeBSD console. */ - return KEY_F(2); - case 'O': - 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[1] - 'O'); - } else - /* Esc [ O == F3 on FreeBSD console. */ - return KEY_F(3); - break; - case 'P': /* Esc [ P == F4 on FreeBSD console. */ - case 'Q': /* Esc [ Q == F5 on FreeBSD console. */ - 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[0] - 'P'); - case 'U': /* Esc [ U == PageDown on Mach console. */ - return KEY_NPAGE; - case 'V': /* Esc [ V == PageUp on Mach console. */ - return KEY_PPAGE; - case 'W': /* Esc [ W == F11 on FreeBSD console. */ - return KEY_F(11); - case 'X': /* Esc [ X == F12 on FreeBSD console. */ - return KEY_F(12); - case 'Y': /* Esc [ Y == End on Mach console. */ - return KEY_END; - case 'Z': /* Esc [ Z == Shift-Tab on ANSI/Linux console/ - * FreeBSD console/xterm/rxvt/Terminal. */ - return SHIFT_TAB; - case 'a': /* Esc [ a == Shift-Up on rxvt/Eterm. */ - case 'b': /* Esc [ b == Shift-Down on rxvt/Eterm. */ - 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[0] - 0x20); - case '[': - 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[1] - '@'); + 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[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[1] - '1'); } - break; - } + } else if (length > 3 && seq[1] == ';') { + *consumed = 4; + switch (seq[2]) { + case '2': + 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[3]); +#ifndef NANO_TINY + case 'F': /* Esc [ 1 ; 2 F == Shift-End on xterm. */ + return SHIFT_END; + case 'H': /* Esc [ 1 ; 2 H == Shift-Home on xterm. */ + return SHIFT_HOME; +#endif + } + break; +#ifndef NANO_TINY + case '9': /* To accommodate iTerm2 in "xterm mode". */ + case '3': + 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. */ + return ALT_DOWN; + case 'C': /* Esc [ 1 ; 3 C == Alt-Right on xterm. */ + return ALT_RIGHT; + case 'D': /* Esc [ 1 ; 3 D == Alt-Left on xterm. */ + return ALT_LEFT; + } + break; + 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[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. */ + return SHIFT_PAGEDOWN; + case 'C': /* Esc [ 1 ; 4 C == Shift-Alt-Right on xterm. */ + return SHIFT_END; + case 'D': /* Esc [ 1 ; 4 D == Shift-Alt-Left on xterm. */ + return SHIFT_HOME; + } + break; +#endif + case '5': + 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. */ + return CONTROL_DOWN; + case 'C': /* Esc [ 1 ; 5 C == Ctrl-Right on xterm. */ + return CONTROL_RIGHT; + case 'D': /* Esc [ 1 ; 5 D == Ctrl-Left on xterm. */ + return CONTROL_LEFT; + case 'F': /* Esc [ 1 ; 5 F == Ctrl-End on xterm. */ + return CONTROL_END; + case 'H': /* Esc [ 1 ; 5 H == Ctrl-Home on xterm. */ + return CONTROL_HOME; + } + break; +#ifndef NANO_TINY + case '6': + 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. */ + return shiftcontroldown; + case 'C': /* Esc [ 1 ; 6 C == Shift-Ctrl-Right on xterm. */ + return shiftcontrolright; + case 'D': /* Esc [ 1 ; 6 D == Shift-Ctrl-Left on xterm. */ + return shiftcontrolleft; + case 'F': /* Esc [ 1 ; 6 F == Shift-Ctrl-End on xterm. */ + return shiftcontrolend; + case 'H': /* Esc [ 1 ; 6 H == Shift-Ctrl-Home on xterm. */ + return shiftcontrolhome; + } + break; +#endif + } + } else if (length > 4 && seq[2] == ';' && seq[4] == '~') + /* Esc [ 1 n ; 2 ~ == F17...F20 on some terminals. */ + *consumed = 5; +#ifdef USE_SLANG + else if (length == 3 && seq[2] == ';') + /* Discard broken sequences that Slang produces. */ + *consumed = 3; +#endif + break; + case '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); + case '1': /* Esc [ 2 1 ~ == F10 on the same. */ + return KEY_F(10); + case '3': /* Esc [ 2 3 ~ == F11 on the same. */ + return KEY_F(11); + case '4': /* Esc [ 2 4 ~ == F12 on the same. */ + return KEY_F(12); + } + } else if (length > 1 && seq[1] == '~') + /* Esc [ 2 ~ == Insert on VT220/VT320/ + * Linux console/xterm/Terminal. */ + return KEY_IC; + else if (length > 3 && seq[1] == ';' && seq[3] == '~') { + /* Esc [ 2 ; x ~ == modified Insert on xterm. */ + *consumed = 4; +#ifndef NANO_TINY + if (seq[2] == '3') + return ALT_INSERT; +#endif + } + else if (length > 4 && seq[2] == ';' && seq[4] == '~') + /* Esc [ 2 n ; 2 ~ == F21...F24 on some terminals. */ + *consumed = 5; +#ifdef USE_SLANG + else if (length == 3 && seq[2] == ';') + /* Discard broken sequences that Slang produces. */ + *consumed = 3; +#endif +#ifndef NANO_TINY + 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 = 4; + if (seq[2] == '0') { + bracketed_paste = TRUE; + return BRACKETED_PASTE_MARKER; + } else if (seq[2] == '1') { + bracketed_paste = FALSE; + return BRACKETED_PASTE_MARKER; + } + } +#endif + break; + case '3': /* Esc [ 3 ~ == Delete on VT220/VT320/ + * Linux console/xterm/Terminal. */ + if (length > 1 && seq[1] == '~') + return KEY_DC; + if (length > 3 && seq[1] == ';' && seq[3] == '~') { + *consumed = 4; +#ifndef NANO_TINY + if (seq[2] == '2') + /* Esc [ 3 ; 2 ~ == Shift-Delete on xterm/Terminal. */ + return SHIFT_DELETE; + if (seq[2] == '3') + /* Esc [ 3 ; 3 ~ == Alt-Delete on xterm/rxvt/Eterm/Terminal. */ + return ALT_DELETE; + if (seq[2] == '5') + /* Esc [ 3 ; 5 ~ == Ctrl-Delete on xterm. */ + return CONTROL_DELETE; + if (seq[2] == '6') + /* Esc [ 3 ; 6 ~ == Ctrl-Shift-Delete on xterm. */ + return controlshiftdelete; +#endif + } +#ifndef NANO_TINY + if (length > 1 && seq[1] == '$') + /* Esc [ 3 $ == Shift-Delete on urxvt. */ + return SHIFT_DELETE; + if (length > 1 && seq[1] == '^') + /* Esc [ 3 ^ == Ctrl-Delete on urxvt. */ + return CONTROL_DELETE; + if (length > 1 && seq[1] == '@') + /* Esc [ 3 @ == Ctrl-Shift-Delete on urxvt. */ + return controlshiftdelete; + if (length > 2 && seq[2] == '~') + /* Esc [ 3 n ~ == F17...F20 on some terminals. */ + *consumed = 3; +#endif + break; + case '4': /* Esc [ 4 ~ == End on VT220/VT320/ + * Linux console/xterm. */ + 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 > 1 && seq[1] == '~') + return KEY_PPAGE; + else if (length > 3 && seq[1] == ';' && seq[3] == '~') { + *consumed = 4; +#ifndef NANO_TINY + if (seq[2] == '2') + return shiftaltup; + 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 > 1 && seq[1] == '~') + return KEY_NPAGE; + else if (length > 3 && seq[1] == ';' && seq[3] == '~') { + *consumed = 4; +#ifndef NANO_TINY + if (seq[2] == '2') + return shiftaltdown; + if (seq[2] == '3') + return ALT_PAGEDOWN; +#endif + } + break; + case '7': /* Esc [ 7 ~ == Home on Eterm/rxvt; + * Esc [ 7 $ == Shift-Home on Eterm/rxvt; + * Esc [ 7 ^ == Control-Home on Eterm/rxvt; + * Esc [ 7 @ == Shift-Control-Home on same. */ + if (length > 1 && seq[1] == '~') + return KEY_HOME; + else if (length > 1 && seq[1] == '$') + return SHIFT_HOME; + else if (length > 1 && seq[1] == '^') + return CONTROL_HOME; +#ifndef NANO_TINY + else if (length > 1 && seq[1] == '@') + return shiftcontrolhome; +#endif + break; + case '8': /* Esc [ 8 ~ == End on Eterm/rxvt; + * Esc [ 8 $ == Shift-End on Eterm/rxvt; + * Esc [ 8 ^ == Control-End on Eterm/rxvt; + * Esc [ 8 @ == Shift-Control-End on same. */ + if (length > 1 && seq[1] == '~') + return KEY_END; + else if (length > 1 && seq[1] == '$') + return SHIFT_END; + else if (length > 1 && seq[1] == '^') + return CONTROL_END; +#ifndef NANO_TINY + else if (length > 1 && seq[1] == '@') + return shiftcontrolend; +#endif + break; + case '9': /* Esc [ 9 == Delete on Mach console. */ + return KEY_DC; + case '@': /* Esc [ @ == Insert on Mach console. */ + return KEY_IC; + case 'A': /* Esc [ A == Up on ANSI/VT220/Linux console/ + * FreeBSD console/Mach console/xterm/Eterm/ + * urxvt/Gnome and Xfce Terminal. */ + 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[0]); + case 'F': /* Esc [ F == End on FreeBSD console/Eterm. */ + return KEY_END; + case 'G': /* Esc [ G == PageDown on FreeBSD console. */ + return KEY_NPAGE; + case 'H': /* Esc [ H == Home on ANSI/VT220/FreeBSD + * console/Mach console/Eterm. */ + return KEY_HOME; + case 'I': /* Esc [ I == PageUp on FreeBSD console. */ + return KEY_PPAGE; + case 'L': /* Esc [ L == Insert on ANSI/FreeBSD console. */ + return KEY_IC; + case 'M': /* Esc [ M == F1 on FreeBSD console. */ + return KEY_F(1); + case 'N': /* Esc [ N == F2 on FreeBSD console. */ + return KEY_F(2); + case 'O': + 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[1] - 'O'); + } else + /* Esc [ O == F3 on FreeBSD console. */ + return KEY_F(3); + break; + case 'P': /* Esc [ P == F4 on FreeBSD console. */ + case 'Q': /* Esc [ Q == F5 on FreeBSD console. */ + 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[0] - 'P'); + case 'U': /* Esc [ U == PageDown on Mach console. */ + return KEY_NPAGE; + case 'V': /* Esc [ V == PageUp on Mach console. */ + return KEY_PPAGE; + case 'W': /* Esc [ W == F11 on FreeBSD console. */ + return KEY_F(11); + case 'X': /* Esc [ X == F12 on FreeBSD console. */ + return KEY_F(12); + case 'Y': /* Esc [ Y == End on Mach console. */ + return KEY_END; + case 'Z': /* Esc [ Z == Shift-Tab on ANSI/Linux console/ + * FreeBSD console/xterm/rxvt/Terminal. */ + return SHIFT_TAB; + case 'a': /* Esc [ a == Shift-Up on rxvt/Eterm. */ + case 'b': /* Esc [ b == Shift-Down on rxvt/Eterm. */ + 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[0] - 0x20); + case '[': + 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[1] - '@'); + } + break; + } return FOREIGN_SEQUENCE; }