aboutsummaryrefslogtreecommitdiff
path: root/libbb
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2009-10-25 23:50:56 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2009-10-25 23:50:56 +0100
commita17eeb847e66824c4d389751cc90415d3fc1c5a3 (patch)
treea5dd027573c002641942191f8ae1f7c7b1f7429e /libbb
parent77c066ea5cf4b1ee606a81e48388ff0b1d019134 (diff)
downloadbusybox-w32-a17eeb847e66824c4d389751cc90415d3fc1c5a3.tar.gz
busybox-w32-a17eeb847e66824c4d389751cc90415d3fc1c5a3.tar.bz2
busybox-w32-a17eeb847e66824c4d389751cc90415d3fc1c5a3.zip
lineedit: handle Ctrl-arrows
function old new delta read_line_input 4629 4824 +195 BB_isalnum - 39 +39 BB_ispunct - 35 +35 BB_isspace - 31 +31 static.esccmds 69 93 +24 vi_word_motion 165 162 -3 vi_back_motion 204 198 -6 vi_end_motion 172 163 -9 bb_iswspace 28 - -28 bb_iswpunct 32 - -32 bb_iswalnum 37 - -37 ------------------------------------------------------------------------------ (add/remove: 3/3 grow/shrink: 5/8 up/down: 334/-129) Total: 205 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'libbb')
-rw-r--r--libbb/lineedit.c97
-rw-r--r--libbb/read_key.c16
2 files changed, 85 insertions, 28 deletions
diff --git a/libbb/lineedit.c b/libbb/lineedit.c
index 5f5beb17c..bfd0e3346 100644
--- a/libbb/lineedit.c
+++ b/libbb/lineedit.c
@@ -16,12 +16,18 @@
16 16
17/* 17/*
18 * Usage and known bugs: 18 * Usage and known bugs:
19 * Terminal key codes are not extensive, and more will probably 19 * Terminal key codes are not extensive, more needs to be added.
20 * need to be added. This version was created on Debian GNU/Linux 2.x. 20 * This version was created on Debian GNU/Linux 2.x.
21 * Delete, Backspace, Home, End, and the arrow keys were tested 21 * Delete, Backspace, Home, End, and the arrow keys were tested
22 * to work in an Xterm and console. Ctrl-A also works as Home. 22 * to work in an Xterm and console. Ctrl-A also works as Home.
23 * Ctrl-E also works as End. 23 * Ctrl-E also works as End.
24 * 24 *
25 * 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
30 *
25 * lineedit does not know that the terminal escape sequences do not 31 * lineedit does not know that the terminal escape sequences do not
26 * take up space on the screen. The redisplay code assumes, unless 32 * take up space on the screen. The redisplay code assumes, unless
27 * told otherwise, that each character in the prompt is a printable 33 * told otherwise, that each character in the prompt is a printable
@@ -64,11 +70,9 @@
64#if ENABLE_FEATURE_ASSUME_UNICODE 70#if ENABLE_FEATURE_ASSUME_UNICODE
65# define BB_NUL L'\0' 71# define BB_NUL L'\0'
66# define CHAR_T wchar_t 72# define CHAR_T wchar_t
67# define BB_isspace(c) iswspace(c) 73static bool BB_isspace(CHAR_T c) { return ((unsigned)c < 256 && isspace(c)); }
68# define BB_isalnum(c) iswalnum(c) 74static bool BB_isalnum(CHAR_T c) { return ((unsigned)c < 256 && isalnum(c)); }
69# define BB_ispunct(c) iswpunct(c) 75static bool BB_ispunct(CHAR_T c) { return ((unsigned)c < 256 && ispunct(c)); }
70# define BB_isprint(c) iswprint(c)
71/* this catches bugs */
72# undef isspace 76# undef isspace
73# undef isalnum 77# undef isalnum
74# undef ispunct 78# undef ispunct
@@ -83,11 +87,6 @@
83# define BB_isspace(c) isspace(c) 87# define BB_isspace(c) isspace(c)
84# define BB_isalnum(c) isalnum(c) 88# define BB_isalnum(c) isalnum(c)
85# define BB_ispunct(c) ispunct(c) 89# define BB_ispunct(c) ispunct(c)
86# if ENABLE_LOCALE_SUPPORT
87# define BB_isprint(c) isprint(c)
88# else
89# define BB_isprint(c) ((c) >= ' ' && (c) != ((unsigned char)'\233'))
90# endif
91#endif 90#endif
92 91
93 92
@@ -1302,24 +1301,10 @@ static void remember_in_history(char *str)
1302#endif /* MAX_HISTORY */ 1301#endif /* MAX_HISTORY */
1303 1302
1304 1303
1304#if ENABLE_FEATURE_EDITING_VI
1305/* 1305/*
1306 * This function is used to grab a character buffer
1307 * from the input file descriptor and allows you to
1308 * a string with full command editing (sort of like
1309 * a mini readline).
1310 *
1311 * The following standard commands are not implemented:
1312 * ESC-b -- Move back one word
1313 * ESC-f -- Move forward one word
1314 * ESC-d -- Delete back one word
1315 * ESC-h -- Delete forward one word
1316 * CTL-t -- Transpose two characters
1317 *
1318 * Minimalist vi-style command line editing available if configured.
1319 * vi mode implemented 2005 by Paul Fox <pgf@foxharp.boston.ma.us> 1306 * vi mode implemented 2005 by Paul Fox <pgf@foxharp.boston.ma.us>
1320 */ 1307 */
1321
1322#if ENABLE_FEATURE_EDITING_VI
1323static void 1308static void
1324vi_Word_motion(int eat) 1309vi_Word_motion(int eat)
1325{ 1310{
@@ -1428,6 +1413,58 @@ vi_back_motion(void)
1428} 1413}
1429#endif 1414#endif
1430 1415
1416/* Modelled after bash 4.0 behavior of Ctrl-<arrow> */
1417static void ctrl_left(void)
1418{
1419 CHAR_T *command = command_ps;
1420
1421 while (1) {
1422 CHAR_T c;
1423
1424 input_backward(1);
1425 if (cursor == 0)
1426 break;
1427 c = command[cursor];
1428 if (c != ' ' && !BB_ispunct(c)) {
1429 /* we reached a "word" delimited by spaces/punct.
1430 * go to its beginning */
1431 while (1) {
1432 c = command[cursor - 1];
1433 if (c == ' ' || BB_ispunct(c))
1434 break;
1435 input_backward(1);
1436 if (cursor == 0)
1437 break;
1438 }
1439 break;
1440 }
1441 }
1442}
1443static void ctrl_right(void)
1444{
1445 CHAR_T *command = command_ps;
1446
1447 while (1) {
1448 CHAR_T c;
1449
1450 c = command[cursor];
1451 if (c == BB_NUL)
1452 break;
1453 if (c != ' ' && !BB_ispunct(c)) {
1454 /* we reached a "word" delimited by spaces/punct.
1455 * go to its end + 1 */
1456 while (1) {
1457 input_forward();
1458 c = command[cursor];
1459 if (c == BB_NUL || c == ' ' || BB_ispunct(c))
1460 break;
1461 }
1462 break;
1463 }
1464 input_forward();
1465 }
1466}
1467
1431 1468
1432/* 1469/*
1433 * read_line_input and its helpers 1470 * read_line_input and its helpers
@@ -2028,6 +2065,12 @@ int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, li
2028 case KEYCODE_LEFT: 2065 case KEYCODE_LEFT:
2029 input_backward(1); 2066 input_backward(1);
2030 break; 2067 break;
2068 case KEYCODE_CTRL_LEFT:
2069 ctrl_left();
2070 break;
2071 case KEYCODE_CTRL_RIGHT:
2072 ctrl_right();
2073 break;
2031 case KEYCODE_DELETE: 2074 case KEYCODE_DELETE:
2032 input_delete(0); 2075 input_delete(0);
2033 break; 2076 break;
diff --git a/libbb/read_key.c b/libbb/read_key.c
index d3832fa6c..410a99995 100644
--- a/libbb/read_key.c
+++ b/libbb/read_key.c
@@ -22,7 +22,6 @@ int64_t FAST_FUNC read_key(int fd, char *buffer)
22 'O','B' |0x80,KEYCODE_DOWN , 22 'O','B' |0x80,KEYCODE_DOWN ,
23 'O','C' |0x80,KEYCODE_RIGHT , 23 'O','C' |0x80,KEYCODE_RIGHT ,
24 'O','D' |0x80,KEYCODE_LEFT , 24 'O','D' |0x80,KEYCODE_LEFT ,
25 /* Ctrl-<arrow>: ESC [ 1 ; 5 x, where x = A/B/C/D */
26 'O','H' |0x80,KEYCODE_HOME , 25 'O','H' |0x80,KEYCODE_HOME ,
27 'O','F' |0x80,KEYCODE_END , 26 'O','F' |0x80,KEYCODE_END ,
28#if 0 27#if 0
@@ -37,15 +36,26 @@ int64_t FAST_FUNC read_key(int fd, char *buffer)
37 '[','B' |0x80,KEYCODE_DOWN , 36 '[','B' |0x80,KEYCODE_DOWN ,
38 '[','C' |0x80,KEYCODE_RIGHT , 37 '[','C' |0x80,KEYCODE_RIGHT ,
39 '[','D' |0x80,KEYCODE_LEFT , 38 '[','D' |0x80,KEYCODE_LEFT ,
39 /* ESC [ 1 ; 2 x, where x = A/B/C/D: Shift-<arrow> */
40 /* ESC [ 1 ; 3 x, where x = A/B/C/D: Alt-<arrow> */
41 /* ESC [ 1 ; 4 x, where x = A/B/C/D: Alt-Shift-<arrow> */
42 /* ESC [ 1 ; 5 x, where x = A/B/C/D: Ctrl-<arrow> - implemented below */
43 /* ESC [ 1 ; 6 x, where x = A/B/C/D: Ctrl-Shift-<arrow> */
40 '[','H' |0x80,KEYCODE_HOME , /* xterm */ 44 '[','H' |0x80,KEYCODE_HOME , /* xterm */
41 /* [ESC] ESC [ [2] H - [Alt-][Shift-]Home */ 45 /* [ESC] ESC [ [2] H - [Alt-][Shift-]Home */
42 '[','F' |0x80,KEYCODE_END , /* xterm */ 46 '[','F' |0x80,KEYCODE_END , /* xterm */
43 '[','1','~' |0x80,KEYCODE_HOME , /* vt100? linux vt? or what? */ 47 '[','1','~' |0x80,KEYCODE_HOME , /* vt100? linux vt? or what? */
44 '[','2','~' |0x80,KEYCODE_INSERT , 48 '[','2','~' |0x80,KEYCODE_INSERT ,
49 /* ESC [ 2 ; 3 ~ - Alt-Insert */
45 '[','3','~' |0x80,KEYCODE_DELETE , 50 '[','3','~' |0x80,KEYCODE_DELETE ,
46 /* [ESC] ESC [ 3 [;2] ~ - [Alt-][Shift-]Delete */ 51 /* [ESC] ESC [ 3 [;2] ~ - [Alt-][Shift-]Delete */
52 /* ESC [ 3 ; 3 ~ - Alt-Delete */
53 /* ESC [ 3 ; 5 ~ - Ctrl-Delete */
47 '[','4','~' |0x80,KEYCODE_END , /* vt100? linux vt? or what? */ 54 '[','4','~' |0x80,KEYCODE_END , /* vt100? linux vt? or what? */
48 '[','5','~' |0x80,KEYCODE_PAGEUP , 55 '[','5','~' |0x80,KEYCODE_PAGEUP ,
56 /* ESC [ 5 ; 3 ~ - Alt-PgUp */
57 /* ESC [ 5 ; 5 ~ - Ctrl-PgUp */
58 /* ESC [ 5 ; 7 ~ - Ctrl-Alt-PgUp */
49 '[','6','~' |0x80,KEYCODE_PAGEDOWN, 59 '[','6','~' |0x80,KEYCODE_PAGEDOWN,
50 '[','7','~' |0x80,KEYCODE_HOME , /* vt100? linux vt? or what? */ 60 '[','7','~' |0x80,KEYCODE_HOME , /* vt100? linux vt? or what? */
51 '[','8','~' |0x80,KEYCODE_END , /* vt100? linux vt? or what? */ 61 '[','8','~' |0x80,KEYCODE_END , /* vt100? linux vt? or what? */
@@ -64,6 +74,10 @@ int64_t FAST_FUNC read_key(int fd, char *buffer)
64 '[','2','3','~'|0x80,KEYCODE_FUN11 , 74 '[','2','3','~'|0x80,KEYCODE_FUN11 ,
65 '[','2','4','~'|0x80,KEYCODE_FUN12 , 75 '[','2','4','~'|0x80,KEYCODE_FUN12 ,
66#endif 76#endif
77 '[','1',';','5','A' |0x80,KEYCODE_CTRL_UP ,
78 '[','1',';','5','B' |0x80,KEYCODE_CTRL_DOWN ,
79 '[','1',';','5','C' |0x80,KEYCODE_CTRL_RIGHT,
80 '[','1',';','5','D' |0x80,KEYCODE_CTRL_LEFT ,
67 0 81 0
68 }; 82 };
69 83