PATCH: FEATURE_EDITING_EXT: Support for more bash/readline(ish) functions in line editing

Denys Vlasenko vda.linux at googlemail.com
Thu Nov 3 12:27:15 UTC 2011


On Mon, Sep 26, 2011 at 9:17 PM, Flemming Madsen <busybox at themadsens.dk> wrote:
> FEATURE_EDITING_EXT: Support for more bash/readline(ish) functions in line
> editing
>
> Signed-off-by: Flemming Madsen <busybox at themadsens.dk>
>
> ---
>
>  1) Completion menu for browsing completion matches with S-Tab/Tab
>      readline function: menu-complete, menu-complete-backward
>      (unbound by default)
>  2) Find commands matching prefix before cursor with M-p M-n
>      readline function: history-search-forward, history-search-backward
>      (unbound by default)
>    I find these easier to use than C-R incremental search,
>    but this is of course a matter of taste.

Since it is not bound by default, only users which are used
to these keystrokes are those who bound these functions
to these exact keys.

How large is this group of users?
I don't want to add something to busybox which is only
used by a handful of users worldwide.

>  3) Insert last word of previous (repeated) command with M-. or M-_
>      readline function: yank-last-arg (M-., M-_)

bash does this, but implementation is too big.
Can you send a patch which implements only this part?

>  4) Word/identifier deletion and movement aliases M-w M-b M-f
>      readline function:  kill-word (M-d), backward-kill-word (M-Rubout)

These _are_ supported by bash, except M-w.

Your implementation of M-d differs from bash behavior.

>  5) Redraw line with C-X (And C-R if incremental search is disabled)
>      readline function: redraw-current-line

These don't work in recent bash (I guess the function is unbound in std
readline config). The same argument about lack of users apply.

Reusing Ctrl-R for two different functions depending on .config
doesn't look like a good idea. User needs to know which .config
was used for this particular bbox binary to use Ctrl-R properly?


I am applying the following patch for now:

diff -d -urpN busybox.3/include/libbb.h busybox.4/include/libbb.h
--- busybox.3/include/libbb.h	2011-10-28 18:09:32.000000000 +0200
+++ busybox.4/include/libbb.h	2011-11-03 13:12:40.096527018 +0100
@@ -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,
-	KEYCODE_CTRL_RIGHT = KEYCODE_RIGHT & ~0x40,
-	KEYCODE_CTRL_LEFT  = KEYCODE_LEFT  & ~0x40,
+	// -12 is reserved for Alt/Ctrl/Shift-TAB
 #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,
+	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,
+	//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
diff -d -urpN busybox.3/libbb/lineedit.c busybox.4/libbb/lineedit.c
--- busybox.3/libbb/lineedit.c	2011-10-28 18:09:32.000000000 +0200
+++ busybox.4/libbb/lineedit.c	2011-11-03 13:26:09.036482071 +0100
@@ -2504,6 +2504,44 @@ int FAST_FUNC read_line_input(line_input
 				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
 			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:
diff -d -urpN busybox.3/libbb/read_key.c busybox.4/libbb/read_key.c
--- busybox.3/libbb/read_key.c	2011-10-28 18:09:32.000000000 +0200
+++ busybox.4/libbb/read_key.c	2011-11-03 12:36:24.291371136 +0100
@@ -40,13 +40,14 @@ int64_t FAST_FUNC read_key(int fd, char
 		'[','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
 		/* '[','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;


-- 
vda


More information about the busybox mailing list