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/lineedit.c | |
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/lineedit.c')
-rw-r--r-- | libbb/lineedit.c | 97 |
1 files changed, 70 insertions, 27 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; |