diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2009-10-25 23:50:56 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2009-10-25 23:50:56 +0100 |
commit | a17eeb847e66824c4d389751cc90415d3fc1c5a3 (patch) | |
tree | a5dd027573c002641942191f8ae1f7c7b1f7429e /libbb | |
parent | 77c066ea5cf4b1ee606a81e48388ff0b1d019134 (diff) | |
download | busybox-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.c | 97 | ||||
-rw-r--r-- | libbb/read_key.c | 16 |
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) | 73 | static bool BB_isspace(CHAR_T c) { return ((unsigned)c < 256 && isspace(c)); } |
68 | # define BB_isalnum(c) iswalnum(c) | 74 | static bool BB_isalnum(CHAR_T c) { return ((unsigned)c < 256 && isalnum(c)); } |
69 | # define BB_ispunct(c) iswpunct(c) | 75 | static 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 | ||
1323 | static void | 1308 | static void |
1324 | vi_Word_motion(int eat) | 1309 | vi_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> */ | ||
1417 | static 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 | } | ||
1443 | static 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 | ||