[PATCH] libbb: Handle repeating escape sequences correctly

Rostislav Skudnov rostislav at tuxera.com
Tue Nov 15 17:26:21 UTC 2016


The following key combinations should repeat correctly when the keys are
pressed and held:
- Alt-b
- Alt-f
- Alt-d
- Alt-Backspace

Escape sequences corresponding to these key combinations are moved from
read_line_input to lineedit_read_key.
---
The problem that this patch fixes is that if you press and hold one of the
above key sequences, the corresponding action occurs only once and does
not repeat.

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.

 include/libbb.h  |  5 ++++
 libbb/lineedit.c | 75 +++++++++++++++++++++++++-------------------------------
 libbb/read_key.c |  5 ++++
 3 files changed, 44 insertions(+), 41 deletions(-)

diff --git a/include/libbb.h b/include/libbb.h
index 20fc732..e0e18da 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -1488,6 +1488,8 @@ enum {
 	KEYCODE_FUN11    = -23,
 	KEYCODE_FUN12    = -24,
 #endif
+	KEYCODE_BACKSPACE = -25,
+	KEYCODE_D         = -26,
 	/* 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),
@@ -1504,6 +1506,9 @@ enum {
 	KEYCODE_ALT_RIGHT  = KEYCODE_RIGHT & ~0x20,
 	KEYCODE_ALT_LEFT   = KEYCODE_LEFT  & ~0x20,
 
+	KEYCODE_ALT_BACKSPACE = KEYCODE_BACKSPACE & ~0x20,
+	KEYCODE_ALT_D         = KEYCODE_D & ~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
diff --git a/libbb/lineedit.c b/libbb/lineedit.c
index 2cc61db..e3eb940 100644
--- a/libbb/lineedit.c
+++ b/libbb/lineedit.c
@@ -23,9 +23,6 @@
  * Ctrl-E also works as End.
  *
  * The following readline-like commands are not implemented:
- * ESC-b -- Move back one word
- * ESC-f -- Move forward one word
- * ESC-d -- Delete forward one word
  * CTL-t -- Transpose two characters
  *
  * lineedit does not know that the terminal escape sequences do not
@@ -2483,6 +2480,40 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman
 			while (cursor > 0 && !BB_isspace(command_ps[cursor-1]))
 				input_backspace();
 			break;
+		case KEYCODE_ALT_D:
+#if ENABLE_FEATURE_EDITING_VI
+			if (state->flags & VI_MODE) {
+				/* insert mode --> command mode */
+				vi_cmdmode = 1;
+				input_backward(1);
+			}
+#endif
+			{
+				/* Delete word forward */
+				int nc, sc = cursor;
+				ctrl_right();
+				nc = cursor - sc;
+				input_backward(nc);
+				while (--nc >= 0)
+					input_delete(1);
+				break;
+			}
+		case KEYCODE_ALT_BACKSPACE:
+#if ENABLE_FEATURE_EDITING_VI
+			if (state->flags & VI_MODE) {
+				/* insert mode --> command mode */
+				vi_cmdmode = 1;
+				input_backward(1);
+			}
+#endif
+			{
+				/* Delete word backward */
+				int sc = cursor;
+				ctrl_left();
+				while (sc-- > cursor)
+					input_delete(1);
+				break;
+			}
 #if ENABLE_FEATURE_REVERSE_SEARCH
 		case CTRL('R'):
 			ic = ic_raw = reverse_i_search();
@@ -2625,44 +2656,6 @@ 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, 50);
-			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 - sc;
-					input_backward(nc);
-					while (--nc >= 0)
-						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 */
 
diff --git a/libbb/read_key.c b/libbb/read_key.c
index ace23de..070bc2f 100644
--- a/libbb/read_key.c
+++ b/libbb/read_key.c
@@ -95,7 +95,12 @@ int64_t FAST_FUNC read_key(int fd, char *buffer, int timeout)
 		/* '[','1',';','3','A' |0x80,KEYCODE_ALT_UP    , - unused */
 		/* '[','1',';','3','B' |0x80,KEYCODE_ALT_DOWN  , - unused */
 		'[','1',';','3','C' |0x80,KEYCODE_ALT_RIGHT,
+		'f'                 |0x80,KEYCODE_ALT_RIGHT,
 		'[','1',';','3','D' |0x80,KEYCODE_ALT_LEFT ,
+		'b'                 |0x80,KEYCODE_ALT_LEFT ,
+		'd'                 |0x80,KEYCODE_ALT_D    ,
+		'\x7f'              |0x80,KEYCODE_ALT_BACKSPACE,
+		'\b'                |0x80,KEYCODE_ALT_BACKSPACE,
 		/* '[','3',';','3','~' |0x80,KEYCODE_ALT_DELETE, - unused */
 		0
 	};
-- 
2.1.4



More information about the busybox mailing list