aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRostislav Skudnov <rostislav@tuxera.com>2016-11-24 15:04:00 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2016-11-24 15:04:00 +0100
commit2e4ef38743c3d4aef109b5cc04429ec1f0e2f6c8 (patch)
tree4224ad31b96cf2b03874083b80da7c4d38995817
parentcb810c48c036f50c19b08df7e161cdb0550a2abd (diff)
downloadbusybox-w32-2e4ef38743c3d4aef109b5cc04429ec1f0e2f6c8.tar.gz
busybox-w32-2e4ef38743c3d4aef109b5cc04429ec1f0e2f6c8.tar.bz2
busybox-w32-2e4ef38743c3d4aef109b5cc04429ec1f0e2f6c8.zip
lineedit: fix handling of repeating Alt-b, Alt-f, Alt-d, Alt-Backspace
These key combinations should repeat correctly when the keys are pressed and held. Before this change, they do this erratically - many repeats are "eaten" because they are treated as unrecognized ESC seqs: ESC 0x7f is treated by Alt+baskspace, but ESC 0x7f ESC 0x7f ESC 0x7f is unrecognized. Escape sequences corresponding to these key combinations are moved from read_line_input to lineedit_read_key. Also, these key sequences are now enabled regardless of whether FEATURE_EDITING_VI is set, since Vim does not actually support these key combinations, but they are present in readline library. function old new delta static.esccmds 93 103 +10 read_line_input 3737 3687 -50 Signed-off-by: Rostislav Skudnov <rostislav@tuxera.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--include/libbb.h76
-rw-r--r--libbb/lineedit.c60
-rw-r--r--libbb/read_key.c12
3 files changed, 68 insertions, 80 deletions
diff --git a/include/libbb.h b/include/libbb.h
index 20fc7329f..bdafcf5a6 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -1463,46 +1463,46 @@ unsigned long long bb_makedev(unsigned major, unsigned minor) FAST_FUNC;
1463 * yet doesn't represent any valid Unicode character. 1463 * yet doesn't represent any valid Unicode character.
1464 * Also, -1 is reserved for error indication and we don't use it. */ 1464 * Also, -1 is reserved for error indication and we don't use it. */
1465enum { 1465enum {
1466 KEYCODE_UP = -2, 1466 KEYCODE_UP = -2,
1467 KEYCODE_DOWN = -3, 1467 KEYCODE_DOWN = -3,
1468 KEYCODE_RIGHT = -4, 1468 KEYCODE_RIGHT = -4,
1469 KEYCODE_LEFT = -5, 1469 KEYCODE_LEFT = -5,
1470 KEYCODE_HOME = -6, 1470 KEYCODE_HOME = -6,
1471 KEYCODE_END = -7, 1471 KEYCODE_END = -7,
1472 KEYCODE_INSERT = -8, 1472 KEYCODE_INSERT = -8,
1473 KEYCODE_DELETE = -9, 1473 KEYCODE_DELETE = -9,
1474 KEYCODE_PAGEUP = -10, 1474 KEYCODE_PAGEUP = -10,
1475 KEYCODE_PAGEDOWN = -11, 1475 KEYCODE_PAGEDOWN = -11,
1476 // -12 is reserved for Alt/Ctrl/Shift-TAB 1476 KEYCODE_BACKSPACE = -12, /* Used only if Alt/Ctrl/Shifted */
1477 KEYCODE_D = -13, /* Used only if Alted */
1477#if 0 1478#if 0
1478 KEYCODE_FUN1 = -13, 1479 KEYCODE_FUN1 = ,
1479 KEYCODE_FUN2 = -14, 1480 KEYCODE_FUN2 = ,
1480 KEYCODE_FUN3 = -15, 1481 KEYCODE_FUN3 = ,
1481 KEYCODE_FUN4 = -16, 1482 KEYCODE_FUN4 = ,
1482 KEYCODE_FUN5 = -17, 1483 KEYCODE_FUN5 = ,
1483 KEYCODE_FUN6 = -18, 1484 KEYCODE_FUN6 = ,
1484 KEYCODE_FUN7 = -19, 1485 KEYCODE_FUN7 = ,
1485 KEYCODE_FUN8 = -20, 1486 KEYCODE_FUN8 = ,
1486 KEYCODE_FUN9 = -21, 1487 KEYCODE_FUN9 = ,
1487 KEYCODE_FUN10 = -22, 1488 KEYCODE_FUN10 = ,
1488 KEYCODE_FUN11 = -23, 1489 KEYCODE_FUN11 = ,
1489 KEYCODE_FUN12 = -24, 1490 KEYCODE_FUN12 = ,
1490#endif 1491#endif
1491 /* Be sure that last defined value is small enough 1492 /* ^^^^^ Be sure that last defined value is small enough.
1492 * to not interfere with Alt/Ctrl/Shift bits. 1493 * Current read_key() code allows going up to -32 (0xfff..fffe0).
1493 * So far we do not exceed -31 (0xfff..fffe1), 1494 * This gives three upper bits in LSB to play with:
1494 * which gives us three upper bits in LSB to play with. 1495 * KEYCODE_foo values are 0xfff..fffXX, lowest XX bits are: scavvvvv,
1496 * s=0 if SHIFT, c=0 if CTRL, a=0 if ALT,
1497 * vvvvv bits are the same for same key regardless of "shift bits".
1495 */ 1498 */
1496 //KEYCODE_SHIFT_TAB = (-12) & ~0x80, 1499 //KEYCODE_SHIFT_... = KEYCODE_... & ~0x80,
1497 //KEYCODE_SHIFT_... = KEYCODE_... & ~0x80, 1500 KEYCODE_CTRL_RIGHT = KEYCODE_RIGHT & ~0x40,
1498 //KEYCODE_CTRL_UP = KEYCODE_UP & ~0x40, 1501 KEYCODE_CTRL_LEFT = KEYCODE_LEFT & ~0x40,
1499 //KEYCODE_CTRL_DOWN = KEYCODE_DOWN & ~0x40, 1502 KEYCODE_ALT_RIGHT = KEYCODE_RIGHT & ~0x20,
1500 KEYCODE_CTRL_RIGHT = KEYCODE_RIGHT & ~0x40, 1503 KEYCODE_ALT_LEFT = KEYCODE_LEFT & ~0x20,
1501 KEYCODE_CTRL_LEFT = KEYCODE_LEFT & ~0x40, 1504 KEYCODE_ALT_BACKSPACE = KEYCODE_BACKSPACE & ~0x20,
1502 //KEYCODE_ALT_UP = KEYCODE_UP & ~0x20, 1505 KEYCODE_ALT_D = KEYCODE_D & ~0x20,
1503 //KEYCODE_ALT_DOWN = KEYCODE_DOWN & ~0x20,
1504 KEYCODE_ALT_RIGHT = KEYCODE_RIGHT & ~0x20,
1505 KEYCODE_ALT_LEFT = KEYCODE_LEFT & ~0x20,
1506 1506
1507 KEYCODE_CURSOR_POS = -0x100, /* 0xfff..fff00 */ 1507 KEYCODE_CURSOR_POS = -0x100, /* 0xfff..fff00 */
1508 /* How long is the longest ESC sequence we know? 1508 /* How long is the longest ESC sequence we know?
diff --git a/libbb/lineedit.c b/libbb/lineedit.c
index 2cc61db40..ac049f57d 100644
--- a/libbb/lineedit.c
+++ b/libbb/lineedit.c
@@ -13,7 +13,6 @@
13 * 13 *
14 * This code is 'as is' with no warranty. 14 * This code is 'as is' with no warranty.
15 */ 15 */
16
17/* 16/*
18 * Usage and known bugs: 17 * Usage and known bugs:
19 * Terminal key codes are not extensive, more needs to be added. 18 * Terminal key codes are not extensive, more needs to be added.
@@ -23,9 +22,6 @@
23 * Ctrl-E also works as End. 22 * Ctrl-E also works as End.
24 * 23 *
25 * The following readline-like commands are not implemented: 24 * The following readline-like commands are not implemented:
26 * ESC-b -- Move back one word
27 * ESC-f -- Move forward one word
28 * ESC-d -- Delete forward one word
29 * CTL-t -- Transpose two characters 25 * CTL-t -- Transpose two characters
30 * 26 *
31 * lineedit does not know that the terminal escape sequences do not 27 * lineedit does not know that the terminal escape sequences do not
@@ -2483,6 +2479,24 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman
2483 while (cursor > 0 && !BB_isspace(command_ps[cursor-1])) 2479 while (cursor > 0 && !BB_isspace(command_ps[cursor-1]))
2484 input_backspace(); 2480 input_backspace();
2485 break; 2481 break;
2482 case KEYCODE_ALT_D: {
2483 /* Delete word forward */
2484 int nc, sc = cursor;
2485 ctrl_right();
2486 nc = cursor - sc;
2487 input_backward(nc);
2488 while (--nc >= 0)
2489 input_delete(1);
2490 break;
2491 }
2492 case KEYCODE_ALT_BACKSPACE: {
2493 /* Delete word backward */
2494 int sc = cursor;
2495 ctrl_left();
2496 while (sc-- > cursor)
2497 input_delete(1);
2498 break;
2499 }
2486#if ENABLE_FEATURE_REVERSE_SEARCH 2500#if ENABLE_FEATURE_REVERSE_SEARCH
2487 case CTRL('R'): 2501 case CTRL('R'):
2488 ic = ic_raw = reverse_i_search(); 2502 ic = ic_raw = reverse_i_search();
@@ -2625,44 +2639,6 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman
2625 vi_cmdmode = 1; 2639 vi_cmdmode = 1;
2626 input_backward(1); 2640 input_backward(1);
2627 } 2641 }
2628 /* Handle a few ESC-<key> combinations the same way
2629 * standard readline bindings (IOW: bash) do.
2630 * Often, Alt-<key> generates ESC-<key>.
2631 */
2632 ic = lineedit_read_key(read_key_buffer, 50);
2633 switch (ic) {
2634 //case KEYCODE_LEFT: - bash doesn't do this
2635 case 'b':
2636 ctrl_left();
2637 break;
2638 //case KEYCODE_RIGHT: - bash doesn't do this
2639 case 'f':
2640 ctrl_right();
2641 break;
2642 //case KEYCODE_DELETE: - bash doesn't do this
2643 case 'd': /* Alt-D */
2644 {
2645 /* Delete word forward */
2646 int nc, sc = cursor;
2647 ctrl_right();
2648 nc = cursor - sc;
2649 input_backward(nc);
2650 while (--nc >= 0)
2651 input_delete(1);
2652 break;
2653 }
2654 case '\b': /* Alt-Backspace(?) */
2655 case '\x7f': /* Alt-Backspace(?) */
2656 //case 'w': - bash doesn't do this
2657 {
2658 /* Delete word backward */
2659 int sc = cursor;
2660 ctrl_left();
2661 while (sc-- > cursor)
2662 input_delete(1);
2663 break;
2664 }
2665 }
2666 break; 2642 break;
2667#endif /* FEATURE_COMMAND_EDITING_VI */ 2643#endif /* FEATURE_COMMAND_EDITING_VI */
2668 2644
diff --git a/libbb/read_key.c b/libbb/read_key.c
index ace23defb..951786869 100644
--- a/libbb/read_key.c
+++ b/libbb/read_key.c
@@ -18,8 +18,20 @@ int64_t FAST_FUNC read_key(int fd, char *buffer, int timeout)
18 /* Known escape sequences for cursor and function keys. 18 /* Known escape sequences for cursor and function keys.
19 * See "Xterm Control Sequences" 19 * See "Xterm Control Sequences"
20 * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html 20 * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html
21 * Array should be sorted from shortest to longest.
21 */ 22 */
22 static const char esccmds[] ALIGN1 = { 23 static const char esccmds[] ALIGN1 = {
24 '\x7f' |0x80,KEYCODE_ALT_BACKSPACE,
25 '\b' |0x80,KEYCODE_ALT_BACKSPACE,
26 'd' |0x80,KEYCODE_ALT_D ,
27 /* lineedit mimics bash: Alt-f and Alt-b are forward/backward
28 * word jumps. We cheat here and make them return ALT_LEFT/RIGHT
29 * keycodes. This way, lineedit need no special code to handle them.
30 * If we'll need to distinguish them, introduce new ALT_F/B keycodes,
31 * and update lineedit to react to them.
32 */
33 'f' |0x80,KEYCODE_ALT_RIGHT,
34 'b' |0x80,KEYCODE_ALT_LEFT,
23 'O','A' |0x80,KEYCODE_UP , 35 'O','A' |0x80,KEYCODE_UP ,
24 'O','B' |0x80,KEYCODE_DOWN , 36 'O','B' |0x80,KEYCODE_DOWN ,
25 'O','C' |0x80,KEYCODE_RIGHT , 37 'O','C' |0x80,KEYCODE_RIGHT ,