aboutsummaryrefslogtreecommitdiff
path: root/libbb
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 /libbb
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>
Diffstat (limited to 'libbb')
-rw-r--r--libbb/lineedit.c60
-rw-r--r--libbb/read_key.c12
2 files changed, 30 insertions, 42 deletions
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 ,