lineedit: add support for M-b, M-f, M-d, M-Backspace
authorDenys Vlasenko <vda.linux@googlemail.com>
Thu, 3 Nov 2011 12:28:22 +0000 (13:28 +0100)
committerDenys Vlasenko <vda.linux@googlemail.com>
Thu, 3 Nov 2011 12:28:22 +0000 (13:28 +0100)
function                                             old     new   delta
ctrl_left                                              -      96     +96
ctrl_right                                             -      76     +76
static.esccmds                                        81      93     +12
read_line_input                                     3876    3885      +9
------------------------------------------------------------------------------
(add/remove: 2/0 grow/shrink: 2/0 up/down: 193/0)             Total: 193 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
include/libbb.h
libbb/lineedit.c
libbb/read_key.c

index 791cdd9..53224fa 100644 (file)
@@ -1358,25 +1358,37 @@ enum {
        KEYCODE_DELETE   =  -9,
        KEYCODE_PAGEUP   = -10,
        KEYCODE_PAGEDOWN = -11,
-
-       KEYCODE_CTRL_UP    = KEYCODE_UP    & ~0x40,
-       KEYCODE_CTRL_DOWN  = KEYCODE_DOWN  & ~0x40,
+       // -12 is reserved for Alt/Ctrl/Shift-TAB
+#if 0
+       KEYCODE_FUN1     = -13,
+       KEYCODE_FUN2     = -14,
+       KEYCODE_FUN3     = -15,
+       KEYCODE_FUN4     = -16,
+       KEYCODE_FUN5     = -17,
+       KEYCODE_FUN6     = -18,
+       KEYCODE_FUN7     = -19,
+       KEYCODE_FUN8     = -20,
+       KEYCODE_FUN9     = -21,
+       KEYCODE_FUN10    = -22,
+       KEYCODE_FUN11    = -23,
+       KEYCODE_FUN12    = -24,
+#endif
+       /* Be sure that last defined value is small enough
+        * to not interfere with Alt/Ctrl/Shift bits.
+        * So far we do not exceed -31 (0xfff..fffe1),
+        * which gives us three upper bits in LSB to play with.
+        */
+       //KEYCODE_SHIFT_TAB  = (-12)         & ~0x80,
+       //KEYCODE_SHIFT_...  = KEYCODE_...   & ~0x80,
+       //KEYCODE_CTRL_UP    = KEYCODE_UP    & ~0x40,
+       //KEYCODE_CTRL_DOWN  = KEYCODE_DOWN  & ~0x40,
        KEYCODE_CTRL_RIGHT = KEYCODE_RIGHT & ~0x40,
        KEYCODE_CTRL_LEFT  = KEYCODE_LEFT  & ~0x40,
-#if 0
-       KEYCODE_FUN1     = -12,
-       KEYCODE_FUN2     = -13,
-       KEYCODE_FUN3     = -14,
-       KEYCODE_FUN4     = -15,
-       KEYCODE_FUN5     = -16,
-       KEYCODE_FUN6     = -17,
-       KEYCODE_FUN7     = -18,
-       KEYCODE_FUN8     = -19,
-       KEYCODE_FUN9     = -20,
-       KEYCODE_FUN10    = -21,
-       KEYCODE_FUN11    = -22,
-       KEYCODE_FUN12    = -23,
-#endif
+       //KEYCODE_ALT_UP     = KEYCODE_UP    & ~0x20,
+       //KEYCODE_ALT_DOWN   = KEYCODE_DOWN  & ~0x20,
+       KEYCODE_ALT_RIGHT  = KEYCODE_RIGHT & ~0x20,
+       KEYCODE_ALT_LEFT   = KEYCODE_LEFT  & ~0x20,
+
        KEYCODE_CURSOR_POS = -0x100, /* 0xfff..fff00 */
        /* How long is the longest ESC sequence we know?
         * We want it big enough to be able to contain
index 603bbfc..0d23288 100644 (file)
@@ -2504,6 +2504,44 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman
                                vi_cmdmode = 1;
                                input_backward(1);
                        }
+                       /* Handle a few ESC-<key> combinations the same way
+                        * standard readline bindings (IOW: bash) do.
+                        * Often, Alt-<key> generates ESC-<key>.
+                        */
+                       ic = lineedit_read_key(read_key_buffer, timeout);
+                       switch (ic) {
+                               //case KEYCODE_LEFT: - bash doesn't do this
+                               case 'b':
+                                       ctrl_left();
+                                       break;
+                               //case KEYCODE_RIGHT: - bash doesn't do this
+                               case 'f':
+                                       ctrl_right();
+                                       break;
+                               //case KEYCODE_DELETE: - bash doesn't do this
+                               case 'd':  /* Alt-D */
+                               {
+                                       /* Delete word forward */
+                                       int nc, sc = cursor;
+                                       ctrl_right();
+                                       nc = cursor;
+                                       input_backward(cursor - sc);
+                                       while (--nc >= cursor)
+                                               input_delete(1);
+                                       break;
+                               }
+                               case '\b':   /* Alt-Backspace(?) */
+                               case '\x7f': /* Alt-Backspace(?) */
+                               //case 'w': - bash doesn't do this
+                               {
+                                       /* Delete word backward */
+                                       int sc = cursor;
+                                       ctrl_left();
+                                       while (sc-- > cursor)
+                                               input_delete(1);
+                                       break;
+                               }
+                       }
                        break;
 #endif /* FEATURE_COMMAND_EDITING_VI */
 
@@ -2532,9 +2570,11 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman
                        input_backward(1);
                        break;
                case KEYCODE_CTRL_LEFT:
+               case KEYCODE_ALT_LEFT: /* bash doesn't do it */
                        ctrl_left();
                        break;
                case KEYCODE_CTRL_RIGHT:
+               case KEYCODE_ALT_RIGHT: /* bash doesn't do it */
                        ctrl_right();
                        break;
                case KEYCODE_HOME:
index 5dcd19c..8d72d2a 100644 (file)
@@ -40,13 +40,14 @@ int64_t FAST_FUNC read_key(int fd, char *buffer, int timeout)
                '[','C'        |0x80,KEYCODE_RIGHT   ,
                '[','D'        |0x80,KEYCODE_LEFT    ,
                /* ESC [ 1 ; 2 x, where x = A/B/C/D: Shift-<arrow> */
-               /* ESC [ 1 ; 3 x, where x = A/B/C/D: Alt-<arrow> */
+               /* ESC [ 1 ; 3 x, where x = A/B/C/D: Alt-<arrow> - implemented below */
                /* ESC [ 1 ; 4 x, where x = A/B/C/D: Alt-Shift-<arrow> */
                /* ESC [ 1 ; 5 x, where x = A/B/C/D: Ctrl-<arrow> - implemented below */
                /* ESC [ 1 ; 6 x, where x = A/B/C/D: Ctrl-Shift-<arrow> */
                '[','H'        |0x80,KEYCODE_HOME    , /* xterm */
-               /* [ESC] ESC [ [2] H - [Alt-][Shift-]Home */
                '[','F'        |0x80,KEYCODE_END     , /* xterm */
+               /* [ESC] ESC [ [2] H - [Alt-][Shift-]Home (End similarly?) */
+               /* '[','Z'        |0x80,KEYCODE_SHIFT_TAB, */
                '[','1','~'    |0x80,KEYCODE_HOME    , /* vt100? linux vt? or what? */
                '[','2','~'    |0x80,KEYCODE_INSERT  ,
                /* ESC [ 2 ; 3 ~ - Alt-Insert */
@@ -86,8 +87,12 @@ int64_t FAST_FUNC read_key(int fd, char *buffer, int timeout)
                /* '[','1',';','5','B' |0x80,KEYCODE_CTRL_DOWN , - unused */
                '[','1',';','5','C' |0x80,KEYCODE_CTRL_RIGHT,
                '[','1',';','5','D' |0x80,KEYCODE_CTRL_LEFT ,
+               /* '[','1',';','3','A' |0x80,KEYCODE_ALT_UP    , - unused */
+               /* '[','1',';','3','B' |0x80,KEYCODE_ALT_DOWN  , - unused */
+               '[','1',';','3','C' |0x80,KEYCODE_ALT_RIGHT,
+               '[','1',';','3','D' |0x80,KEYCODE_ALT_LEFT ,
+               /* '[','3',';','3','~' |0x80,KEYCODE_ALT_DELETE, - unused */
                0
-               /* ESC [ Z - Shift-Tab */
        };
 
        pfd.fd = fd;