[prev in list] [next in list] [prev in thread] [next in thread] 

List:       busybox
Subject:    PATCH: Support for more bash/readline(ish) functions
From:       Flemming Madsen <busybox () themadsens ! dk>
Date:       2011-09-20 18:41:36
Message-ID: CACWu54XGzX+tWoZMZJWuWSoQ4CpEhqA0P54Txx7V_nRCtasP5w () mail ! gmail ! com
[Download RAW message or body]

05-lineedit-meta-commands.patch
----------

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

 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.
 3) Insert last word of previous (repeated) command with M-. or M-_
      readline function: yank-last-arg (M-., M-_)
 4) Word/identifier deletion and movement aliases M-w M-b M-f
      readline function:  kill-word (M-d), backward-kill-word (M-Rubout)
 5) Redraw line with C-X (And C-R if incremental search is disabled)
      readline function: redraw-current-line

["05-lineedit-meta-commands.patch" (text/x-patch)]

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

 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.
 3) Insert last word of previous (repeated) command with M-. or M-_
      readline function: yank-last-arg (M-., M-_)
 4) Word/identifier deletion and movement aliases M-w M-b M-f
      readline function:  kill-word (M-d), backward-kill-word (M-Rubout)
 5) Redraw line with C-X (And C-R if incremental search is disabled)
      readline function: redraw-current-line

Index: busybox/busybox-1.19.2/include/libbb.h
===================================================================
--- busybox.orig/busybox-1.19.2/include/libbb.h	2011-09-19 18:20:56.000000000 +0200
+++ busybox/busybox-1.19.2/include/libbb.h	2011-09-19 18:38:04.000000000 +0200
@@ -1352,34 +1352,42 @@
  * yet doesn't represent any valid Unicode character.
  * Also, -1 is reserved for error indication and we don't use it. */
 enum {
-	KEYCODE_UP       =  -2,
-	KEYCODE_DOWN     =  -3,
-	KEYCODE_RIGHT    =  -4,
-	KEYCODE_LEFT     =  -5,
-	KEYCODE_HOME     =  -6,
-	KEYCODE_END      =  -7,
-	KEYCODE_INSERT   =  -8,
-	KEYCODE_DELETE   =  -9,
-	KEYCODE_PAGEUP   = -10,
-	KEYCODE_PAGEDOWN = -11,
+	KEYCODE_UP        =  -2,
+	KEYCODE_DOWN      =  -3,
+	KEYCODE_RIGHT     =  -4,
+	KEYCODE_LEFT      =  -5,
+	KEYCODE_HOME      =  -6,
+	KEYCODE_END       =  -7,
+	KEYCODE_INSERT    =  -8,
+	KEYCODE_DELETE    =  -9,
+	KEYCODE_PAGEUP    = -10,
+	KEYCODE_PAGEDOWN  = -11,
+	KEYCODE_SHIFT_TAB = -12,
 
-	KEYCODE_CTRL_UP    = KEYCODE_UP    & ~0x40,
-	KEYCODE_CTRL_DOWN  = KEYCODE_DOWN  & ~0x40,
-	KEYCODE_CTRL_RIGHT = KEYCODE_RIGHT & ~0x40,
-	KEYCODE_CTRL_LEFT  = KEYCODE_LEFT  & ~0x40,
+	/* Using this bit reduces keycode count to 32 - Inline them above instead ? */
+	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_ALT_DELETE = KEYCODE_DELETE & ~0x20,
+
+	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,
+	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
 	KEYCODE_CURSOR_POS = -0x100, /* 0xfff..fff00 */
 	/* How long is the longest ESC sequence we know?
Index: busybox/busybox-1.19.2/libbb/lineedit.c
===================================================================
--- busybox.orig/busybox-1.19.2/libbb/lineedit.c	2011-09-19 18:20:56.000000000 +0200
+++ busybox/busybox-1.19.2/libbb/lineedit.c	2011-09-19 18:38:04.000000000 +0200
@@ -145,6 +145,11 @@
 #if ENABLE_FEATURE_TAB_COMPLETION
 	char **matches;
 	unsigned num_matches;
+#if ENABLE_FEATURE_EDITING_EXT
+	int cmpmenu_org_pfx;
+	int cmpmenu_curlen;
+	int cmpmenu_curpos;
+#endif
 #endif
 
 #if ENABLE_FEATURE_EDITING_VI
@@ -1074,19 +1079,58 @@
 	return s;
 }
 
+enum {
+	TS_LAST_NOT_TAB = 0,
+	TS_LAST_WAS_TAB,
+	TS_LIST_WAS_PRINTED,
+	TS_MENU_MODE,
+};
+
+
 /* Do TAB completion */
-static NOINLINE void input_tab(smallint *lastWasTab)
+static NOINLINE void input_tab(smallint *lastWasTab, smallint is_meta)
 {
 	char *chosen_match;
 	char *match_buf;
 	size_t len_found;
 	/* Length of string used for matching */
 	unsigned match_pfx_len = match_pfx_len;
+#if !ENABLE_FEATURE_EDITING_EXT
+#define cur_remlen 0
+#else
+#define cmpmenu_org_pfx  (S.cmpmenu_org_pfx)
+#define cmpmenu_curlen   (S.cmpmenu_curlen)
+#define cmpmenu_curpos   (S.cmpmenu_curpos)
+	int cur_remlen = 0;
+# endif
 	int find_type;
 # if ENABLE_UNICODE_SUPPORT
 	/* cursor pos in command converted to multibyte form */
 	int cursor_mb;
 # endif
+
+	auto void save_cmdline_prefix_in_matchbuf(void);
+	void save_cmdline_prefix_in_matchbuf(void)
+	{
+		/* Make a local copy of the string up to the position of the cursor.
+		 * build_match_prefix will expand it into int16_t's, need to allocate
+		 * twice as much as the string_len+1.
+		 * (we then also (ab)use this extra space later - see (**))
+		 */
+		match_buf = xmalloc(MAX_LINELEN * sizeof(int16_t));
+# if !ENABLE_UNICODE_SUPPORT
+		save_string(match_buf, cursor + 1); /* +1 for NUL */
+# else
+		{
+			CHAR_T wc = command_ps[cursor];
+			command_ps[cursor] = BB_NUL;
+			save_string(match_buf, MAX_LINELEN);
+			command_ps[cursor] = wc;
+			cursor_mb = strlen(match_buf);
+		}
+# endif
+	}
+
 	if (!(state->flags & TAB_COMPLETION))
 		return;
 
@@ -1094,36 +1138,65 @@
 		/* The last char was a TAB too.
 		 * Print a list of all the available choices.
 		 */
+#if ENABLE_FEATURE_EDITING_EXT
+		if (num_matches > 1 && ((is_meta && *lastWasTab > TS_LAST_WAS_TAB) ||
+								*lastWasTab > TS_LIST_WAS_PRINTED)) {
+			int wholeword = 1;
+			*lastWasTab = TS_MENU_MODE;
+			cur_remlen = cmpmenu_curlen;
+			save_cmdline_prefix_in_matchbuf(); /* setup match_buf & cursor_mb  */
+#if ENABLE_UNICODE_SUPPORT
+			cursor_mb -= cmpmenu_curlen;
+#else
+			cursor -= cmpmenu_curlen;
+# endif
+
+			if (is_meta && cmpmenu_curpos < num_matches) { /* Forward one match */
+				chosen_match = quote_special_chars(matches[++cmpmenu_curpos - 1]);
+			} else if (!is_meta && cmpmenu_curpos > 1) {  /* Backward one match */
+				chosen_match = quote_special_chars(matches[--cmpmenu_curpos - 1]);
+			} else {                           /* Back to start */
+				beep();
+				wholeword = 0;
+				cmpmenu_curpos = is_meta ? 0 : (num_matches + 1);
+				chosen_match = quote_special_chars(matches[0]);
+				chosen_match[cmpmenu_org_pfx] = 0;
+			}
+			match_pfx_len = 0;
+			len_found = strlen(chosen_match);
+			if (wholeword && chosen_match[len_found-1] != '/') {
+				chosen_match[len_found] = ' ';
+				chosen_match[++len_found] = '\0';
+			}
+			cmpmenu_curlen = len_found;
+#if 0
+			printf("\nLW:%d CR:%d CL:%d ORG:%d CRS:%d M'%s'\n",
+				   *lastWasTab, cur_remlen, cmpmenu_curlen,
+				   cmpmenu_org_pfx, cursor, chosen_match);
+#endif
+			goto do_redraw;
+		} else
+#endif
 		if (num_matches > 0) {
 			/* cursor will be changed by goto_new_line() */
 			int sav_cursor = cursor;
+			*lastWasTab = TS_LIST_WAS_PRINTED;
 			goto_new_line();
 			showfiles();
 			redraw(0, command_len - sav_cursor);
 		}
 		return;
 	}
+#if ENABLE_FEATURE_EDITING_EXT
+	cmpmenu_org_pfx = 0; /* reset */
+	cmpmenu_curlen = 0;
+	cmpmenu_curpos = 0;
+#endif
 
-	*lastWasTab = 1;
+	*lastWasTab = TS_LAST_WAS_TAB;
 	chosen_match = NULL;
 
-	/* Make a local copy of the string up to the position of the cursor.
-	 * build_match_prefix will expand it into int16_t's, need to allocate
-	 * twice as much as the string_len+1.
-	 * (we then also (ab)use this extra space later - see (**))
-	 */
-	match_buf = xmalloc(MAX_LINELEN * sizeof(int16_t));
-# if !ENABLE_UNICODE_SUPPORT
-	save_string(match_buf, cursor + 1); /* +1 for NUL */
-# else
-	{
-		CHAR_T wc = command_ps[cursor];
-		command_ps[cursor] = BB_NUL;
-		save_string(match_buf, MAX_LINELEN);
-		command_ps[cursor] = wc;
-		cursor_mb = strlen(match_buf);
-	}
-# endif
+	save_cmdline_prefix_in_matchbuf();
 	find_type = build_match_prefix(match_buf);
 
 	/* Free up any memory already allocated */
@@ -1206,6 +1279,11 @@
 		}
 	}
 
+#if ENABLE_FEATURE_EDITING_EXT
+	cmpmenu_org_pfx = len_found;
+	cmpmenu_curlen = len_found;
+#endif
+do_redraw:
 # if !ENABLE_UNICODE_SUPPORT
 	/* Have space to place the match? */
 	/* The result consists of three parts with these lengths: */
@@ -1214,7 +1292,7 @@
 	if ((int)(len_found - match_pfx_len + command_len) < S.maxsize) {
 		int pos;
 		/* save tail */
-		strcpy(match_buf, &command_ps[cursor]);
+		strcpy(match_buf, &command_ps[cursor + cur_remlen]);
 		/* add match and tail */
 		sprintf(&command_ps[cursor], "%s%s", chosen_match + match_pfx_len, match_buf);
 		command_len = strlen(command_ps);
@@ -1233,7 +1311,7 @@
 		if ((int)(len_found - match_pfx_len + len) < MAX_LINELEN) {
 			int pos;
 			/* save tail */
-			strcpy(match_buf, &command[cursor_mb]);
+			strcpy(match_buf, &command[cursor_mb + cur_remlen]);
 			/* where do we want to have cursor after all? */
 			strcpy(&command[cursor_mb], chosen_match + match_pfx_len);
 			len = load_string(command);
@@ -1952,6 +2030,36 @@
 # define isrtl_str() 0
 #endif
 
+static void insert_text(const CHAR_T *c, int n)
+{
+	while (n--) {
+		CHAR_T ic = *c++;
+
+		command_len++;
+		if (cursor == (command_len - 1)) {
+			/* We are at the end, append */
+			command_ps[cursor] = ic;
+			command_ps[cursor + 1] = BB_NUL;
+			put_cur_glyph_and_inc_cursor();
+			if (unicode_bidi_isrtl(ic))
+				input_backward(1);
+		} else {
+			/* In the middle, insert */
+			int sc = cursor;
+
+			memmove(command_ps + sc + 1, command_ps + sc,
+				(command_len - sc) * sizeof(command_ps[0]));
+			command_ps[sc] = ic;
+			/* is right-to-left char, or neutral one (e.g. comma) was just added to rtl text? */
+			if (!isrtl_str())
+				sc++; /* no */
+			put_till_end_and_adv_cursor();
+			/* to prev x pos + 1 */
+			input_backward(cursor - sc);
+		}
+	}
+}
+
 /* leave out the "vi-mode"-only case labels if vi editing isn't
  * configured. */
 #define vi_case(caselabel) IF_FEATURE_EDITING_VI(case caselabel)
@@ -1959,6 +2067,7 @@
 /* convert uppercase ascii to equivalent control char, for readability */
 #undef CTRL
 #define CTRL(a) ((a) & ~0x40)
+#define META(a) ((a) | 0x80)
 
 enum {
 	VI_CMDMODE_BIT = 0x40000000,
@@ -2110,6 +2219,10 @@
 #if ENABLE_FEATURE_EDITING_VI
 	smallint vi_cmdmode = 0;
 #endif
+#if ENABLE_FEATURE_EDITING_EXT && MAX_HISTORY > 0
+	int search_prefix = 0;
+	int yank_end = 0;
+#endif
 	struct termios initial_settings;
 	struct termios new_settings;
 	char read_key_buffer[KEYCODE_BUFFER_SIZE];
@@ -2272,7 +2385,7 @@
 			break;
 #if ENABLE_FEATURE_TAB_COMPLETION
 		case '\t':
-			input_tab(&lastWasTab);
+			input_tab(&lastWasTab, FALSE);
 			break;
 #endif
 		case CTRL('K'):
@@ -2285,6 +2398,10 @@
 		vi_case(CTRL('L')|VI_CMDMODE_BIT:)
 			/* Control-l -- clear screen */
 			printf(ESC"[H"); /* cursor to top,left */
+#if !ENABLE_FEATURE_REVERSE_SEARCH
+		case CTRL('R'):
+#endif
+		case CTRL('X'): /* Redraw line */
 			redraw(0, command_len - cursor);
 			break;
 #if MAX_HISTORY > 0
@@ -2457,14 +2574,186 @@
 				bb_putchar('\b');
 			}
 			break;
+#endif /* FEATURE_COMMAND_EDITING_VI */
+#if ENABLE_FEATURE_EDITING_EXT
+		case KEYCODE_SHIFT_TAB:
+		case KEYCODE_ALT_UP:
+		case KEYCODE_ALT_DOWN:
+		case KEYCODE_ALT_LEFT:
+		case KEYCODE_ALT_RIGHT:
+		case KEYCODE_ALT_DELETE:
+			// Continue into ESC handling
+#endif
 		case '\x1b': /* ESC */
+#if ENABLE_FEATURE_EDITING_VI
 			if (state->flags & VI_MODE) {
 				/* insert mode --> command mode */
-				vi_cmdmode = 1;
-				input_backward(1);
+				if (ic == '\x1b') {
+					vi_cmdmode = 1;
+					input_backward(1);
+				}
+				break;
+			}
+#endif
+#if ENABLE_FEATURE_EDITING_EXT
+			{
+				int i2 = ic == '\x1b' ? read_key(STDIN_FILENO, read_key_buffer, timeout) : ic;
+
+				switch (i2) {
+				 case KEYCODE_ALT_LEFT:
+				 case KEYCODE_LEFT:
+				 case 'b':
+				   ctrl_left();
+				   break;
+				 case KEYCODE_ALT_RIGHT:
+				 case KEYCODE_RIGHT:
+				 case 'f':
+				   ctrl_right();
+				   break;
+				 case KEYCODE_ALT_DELETE:
+				 case KEYCODE_DELETE:
+				 case 'd': {
+				   /* M-d Delete word forward */
+				   int nc, sc = cursor;
+				   ctrl_right();
+				   nc = cursor;
+				   input_backward(cursor - sc);
+				   while (nc >= 0 && nc-- >= cursor)
+					input_delete(1);
+				   break;
+				 }
+				 case '\b':   /* ^H */
+				 case '\x7f': /* DEL */
+				 case 'w': {
+				   /* M-w Delete word backward */
+				   int sc = cursor;
+				   ctrl_left();
+				   while (sc-- > cursor)
+					 input_delete(1);
+				   break;
+				 }
+
+#if ENABLE_FEATURE_TAB_COMPLETION
+				case KEYCODE_SHIFT_TAB:
+				case '\t':
+					input_tab(&lastWasTab, TRUE);
+					break;
+#endif
+#if MAX_HISTORY > 0
+				case KEYCODE_ALT_UP:
+				case KEYCODE_UP:
+				case 'p':
+				case KEYCODE_ALT_DOWN:
+				case KEYCODE_DOWN:
+				case 'n':
+				{
+					int is_up = 0;
+					switch (i2) {
+						case KEYCODE_ALT_UP:
+						case KEYCODE_UP:
+						case 'p':
+							is_up = 1;
+					}
+					/* Meta-n -- Search next command from history */
+					search_prefix = cursor;
+					if (state->flags & DO_HISTORY) {
+						int ch = state->cur_history + (is_up ? -1 : 1);
+# if ENABLE_UNICODE_SUPPORT
+						char cmdpfx[MAX_LINELEN];
+						CHAR_T sc = command_ps[search_prefix];
+						int pfxlen;
+						command_ps[search_prefix] = BB_NUL;
+						pfxlen = save_string(cmdpfx, sizeof(cmdpfx));
+						command_ps[search_prefix] = sc;
+#else
+						int pfxlen = search_prefix;
+						char *cmdpfx = command_ps;
+#endif
+						while ((!is_up && ch < state->cnt_history) ||
+							   (is_up && ch >= 0)) {
+							if (state->history[ch] && 0 == strncmp(cmdpfx, state->history[ch], pfxlen)) {
+								state->cur_history = ch;
+								goto rewrite_line;
+							}
+							ch += is_up ? -1 : 1;
+						}
+					}
+					if (!is_up && cursor < command_len) {
+						command_ps[cursor] = BB_NUL;
+						command_len = cursor;
+						redraw(cmdedit_y, (state->flags & VI_MODE) ? 9999 : 0);
+						state->cur_history = state->cnt_history;
+					}
+					beep();
+					break;
+				}
+				case '.':
+				case '_':
+					// Insert last word from previous command. More previous on repeat
+					if (yank_end == 0) {
+						yank_end = state->cnt_history;
+						search_prefix = cursor;
+					}
+					if ((state->flags & DO_HISTORY) && yank_end > 0) {
+						char *cmd;
+						int  ix;
+						int cursor_middle;
+						smallint in_sq = 0, in_dq = 0;
+
+						while (cursor > search_prefix)
+							input_backspace();
+
+						cmd = state->history[--yank_end];
+						if (!cmd)
+							break;
+
+						/* Find last shell token in line (approximately) */
+						for (ix = strlen(cmd) - 1; ix > 0; ix--) {
+							if (cmd[ix] == '"' || cmd[ix] == '`') {
+								if (in_dq == cmd[ix] && (ix == 0 || cmd[ix-1] != '\\'))
+									in_dq = 0;
+								else if (!in_sq && !in_dq)
+									in_dq = cmd[ix];
+							}
+							else if (cmd[ix] == '\'' && !in_dq)
+								in_sq = in_sq ? 0 : 1;
+							if (!in_dq && !in_sq &&
+								strchr(" \t<>;&|", cmd[ix-1]) && (ix < 2 || cmd[ix-2] != '\\'))
+							 break;
+						}
+						if ((int)command_len > maxsize - strlen(cmd + ix) - 2)
+							break;
+//  printf("\nYE:%d:%d SP:%d IX:%d'%s'\n", yank_end, state->cnt_history, search_prefix, ix, cmd + ix);
+
+#if ENABLE_UNICODE_SUPPORT
+						{
+							int siz = strlen(cmd + ix);
+							CHAR_T *word = xzalloc((siz + 1) * sizeof(command_ps[0]));
+							ssize_t wlen = mbstowcs(word, cmd + ix, (siz + 1) * sizeof(command_ps[0]));
+							cursor_middle = cursor + wlen;
+							if (cursor == command_len - 1) {
+								CHAR_T spc = ' ';
+								insert_text(&spc, 1);
+								cursor_middle = 0;
+							}
+							insert_text(word, wlen);
+							free(word);
+						}
+#else
+						cursor_middle = cursor + strlen(cmd + ix);
+						if (cursor == command_len - 1) {
+							insert_text(" ", 1);
+							cursor_middle = 0;
+						}
+						insert_text(cmd + ix, strlen(cmd + ix));
+#endif
+					}
+					break;
+#endif
+				}
 			}
+#endif
 			break;
-#endif /* FEATURE_COMMAND_EDITING_VI */
 
 #if MAX_HISTORY > 0
 		case KEYCODE_UP:
@@ -2481,6 +2770,11 @@
 			command_len = load_string(state->history[state->cur_history] ?
 					state->history[state->cur_history] : "");
 			/* redraw and go to eol (bol, in vi) */
+#if ENABLE_FEATURE_EDITING_EXT
+			if (search_prefix > 0)
+				redraw(cmdedit_y, command_len - search_prefix);
+			else
+#endif
 			redraw(cmdedit_y, (state->flags & VI_MODE) ? 9999 : 0);
 			break;
 #endif
@@ -2555,27 +2849,13 @@
 				break;
 			}
 
-			command_len++;
-			if (cursor == (command_len - 1)) {
-				/* We are at the end, append */
-				command_ps[cursor] = ic;
-				command_ps[cursor + 1] = BB_NUL;
-				put_cur_glyph_and_inc_cursor();
-				if (unicode_bidi_isrtl(ic))
-					input_backward(1);
-			} else {
-				/* In the middle, insert */
-				int sc = cursor;
-
-				memmove(command_ps + sc + 1, command_ps + sc,
-					(command_len - sc) * sizeof(command_ps[0]));
-				command_ps[sc] = ic;
-				/* is right-to-left char, or neutral one (e.g. comma) was just added to rtl text? */
-				if (!isrtl_str())
-					sc++; /* no */
-				put_till_end_and_adv_cursor();
-				/* to prev x pos + 1 */
-				input_backward(cursor - sc);
+#if ENABLE_FEATURE_EDITING_EXT
+			search_prefix = 0;
+			yank_end = 0;
+#endif
+			{
+				CHAR_T ics[1] = { ic };
+				insert_text(ics, 1);
 			}
 			break;
 		} /* switch (ic) */
@@ -2584,7 +2864,7 @@
 			break;
 
 #if ENABLE_FEATURE_TAB_COMPLETION
-		if (ic_raw != '\t')
+		if (ic_raw != '\t' && ic_raw != KEYCODE_SHIFT_TAB)
 			lastWasTab = 0;
 #endif
 	} /* while (1) */
Index: busybox/busybox-1.19.2/libbb/Config.src
===================================================================
--- busybox.orig/busybox-1.19.2/libbb/Config.src	2011-09-19 18:23:42.000000000 +0200
+++ busybox/busybox-1.19.2/libbb/Config.src	2011-09-19 18:38:04.000000000 +0200
@@ -78,6 +78,15 @@
 	  Enable vi-style line editing. In shells, this mode can be
 	  turned on and off with "set -o vi" and "set +o vi".
 
+config FEATURE_EDITING_EXT
+	bool "Additional Meta key line editing commands"
+	default n
+	depends on FEATURE_EDITING
+	help
+	  Extra editing commands. Use either Alt-Key or Esc-Key
+	  Enable M-b M-f M-w M-d M-w M-n M-p and M-. M-_ editing commands
+	  M-n and M-p are history search back and forth.
+
 config FEATURE_EDITING_HISTORY
 	int "History size"
 	# Don't allow way too big values here, code uses fixed "char *history[N]" struct member
Index: busybox/busybox-1.19.2/libbb/read_key.c
===================================================================
--- busybox.orig/busybox-1.19.2/libbb/read_key.c	2011-09-19 18:38:27.000000000 +0200
+++ busybox/busybox-1.19.2/libbb/read_key.c	2011-09-19 18:39:18.000000000 +0200
@@ -47,6 +47,7 @@
 		'[','H'        |0x80,KEYCODE_HOME    , /* xterm */
 		/* [ESC] ESC [ [2] H - [Alt-][Shift-]Home */
 		'[','F'        |0x80,KEYCODE_END     , /* xterm */
+		'[','Z'        |0x80,KEYCODE_SHIFT_TAB,
 		'[','1','~'    |0x80,KEYCODE_HOME    , /* vt100? linux vt? or what? */
 		'[','2','~'    |0x80,KEYCODE_INSERT  ,
 		/* ESC [ 2 ; 3 ~ - Alt-Insert */
@@ -86,6 +87,11 @@
 		/* '[','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,
+		'[','1',';','3','B' |0x80,KEYCODE_ALT_DOWN ,
+		'[','1',';','3','C' |0x80,KEYCODE_ALT_RIGHT,
+		'[','1',';','3','D' |0x80,KEYCODE_ALT_LEFT ,
+		'[','3',';','3','~' |0x80,KEYCODE_ALT_DELETE ,
 		0
 		/* ESC [ Z - Shift-Tab */
 	};


_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic