diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-01-21 19:18:59 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-01-21 19:18:59 +0000 |
commit | 47bdb3ac482e8ccfa073b1c17fdf52d3721952b6 (patch) | |
tree | c1b572a5d0e3a9a30ca9011a16aad9bb0633a201 | |
parent | 82b39e83ab13660f0b76a52519e1ac44e30fff7c (diff) | |
download | busybox-w32-47bdb3ac482e8ccfa073b1c17fdf52d3721952b6.tar.gz busybox-w32-47bdb3ac482e8ccfa073b1c17fdf52d3721952b6.tar.bz2 busybox-w32-47bdb3ac482e8ccfa073b1c17fdf52d3721952b6.zip |
cmdedit: small optimizations
-rw-r--r-- | shell/cmdedit.c | 177 |
1 files changed, 104 insertions, 73 deletions
diff --git a/shell/cmdedit.c b/shell/cmdedit.c index 617f3a29a..1143ded77 100644 --- a/shell/cmdedit.c +++ b/shell/cmdedit.c | |||
@@ -28,6 +28,51 @@ | |||
28 | - not true viewing if length prompt less terminal width | 28 | - not true viewing if length prompt less terminal width |
29 | */ | 29 | */ |
30 | 30 | ||
31 | /* | ||
32 | CONFIG_FEATURE_COMMAND_EDITING=y | ||
33 | # CONFIG_FEATURE_COMMAND_EDITING_VI is not set | ||
34 | CONFIG_FEATURE_COMMAND_HISTORY=15 | ||
35 | # CONFIG_FEATURE_COMMAND_SAVEHISTORY is not set | ||
36 | # CONFIG_FEATURE_COMMAND_TAB_COMPLETION is not set | ||
37 | # CONFIG_FEATURE_COMMAND_USERNAME_COMPLETION is not set | ||
38 | # CONFIG_FEATURE_SH_FANCY_PROMPT is not set | ||
39 | Sizes with the above: | ||
40 | # size cmdedit.o | ||
41 | text data bss dec hex filename | ||
42 | 2374 4 228 2606 a2e cmdedit.o | ||
43 | # nm --size-sort cmdedit.o | ||
44 | 00000004 b cmdedit_prmt_len | ||
45 | 00000004 b cmdedit_prompt | ||
46 | 00000004 d cmdedit_termw | ||
47 | 00000004 b cmdedit_x | ||
48 | 00000004 b cmdedit_y | ||
49 | 00000004 b command_ps | ||
50 | 00000004 b cur_history | ||
51 | 00000004 b cursor | ||
52 | 00000004 b handlers_sets | ||
53 | 00000004 b len | ||
54 | 00000004 b n_history | ||
55 | 00000004 b previous_SIGWINCH_handler | ||
56 | 00000009 t beep | ||
57 | 00000017 t goto_new_line | ||
58 | 0000001a t input_end | ||
59 | 0000001b t input_backspace | ||
60 | 0000001e t input_forward | ||
61 | 00000027 t get_next_history | ||
62 | 00000036 t put_prompt | ||
63 | 00000039 t redraw | ||
64 | 0000003c b initial_settings | ||
65 | 0000003c b new_settings | ||
66 | 00000040 b history | ||
67 | 00000047 t input_delete | ||
68 | 0000004d t get_previous_history | ||
69 | 00000059 t cmdedit_reset_term | ||
70 | 0000006c t cmdedit_set_out_char | ||
71 | 00000087 t input_backward | ||
72 | 000000a1 t win_changed | ||
73 | 0000053c T cmdedit_read_input | ||
74 | */ | ||
75 | |||
31 | #include <sys/ioctl.h> | 76 | #include <sys/ioctl.h> |
32 | #include "busybox.h" | 77 | #include "busybox.h" |
33 | #include "cmdedit.h" | 78 | #include "cmdedit.h" |
@@ -86,7 +131,7 @@ enum { | |||
86 | 131 | ||
87 | static int cmdedit_x; /* real x terminal position */ | 132 | static int cmdedit_x; /* real x terminal position */ |
88 | static int cmdedit_y; /* pseudoreal y terminal position */ | 133 | static int cmdedit_y; /* pseudoreal y terminal position */ |
89 | static int cmdedit_prmt_len; /* length of prompt without colores string */ | 134 | static int cmdedit_prmt_len; /* length of prompt (without colors etc) */ |
90 | 135 | ||
91 | static int cursor; | 136 | static int cursor; |
92 | static int len; | 137 | static int len; |
@@ -179,40 +224,34 @@ static void beep(void) | |||
179 | } | 224 | } |
180 | 225 | ||
181 | /* Move back one character */ | 226 | /* Move back one character */ |
182 | /* special for slow terminal */ | 227 | /* (optimized for slow terminals) */ |
183 | static void input_backward(int num) | 228 | static void input_backward(unsigned num) |
184 | { | 229 | { |
230 | int count_y; | ||
231 | |||
185 | if (num > cursor) | 232 | if (num > cursor) |
186 | num = cursor; | 233 | num = cursor; |
187 | cursor -= num; /* new cursor (in command, not terminal) */ | 234 | if (!num) |
235 | return; | ||
236 | cursor -= num; | ||
188 | 237 | ||
189 | if (cmdedit_x >= num) { | 238 | if (cmdedit_x >= num) { |
190 | cmdedit_x -= num; | 239 | cmdedit_x -= num; |
191 | if (num <= 4) | 240 | if (num <= 4) { |
192 | while (num > 0) { | 241 | do putchar('\b'); while (--num); |
193 | putchar('\b'); | 242 | return; |
194 | num--; | 243 | } |
195 | } | 244 | printf("\033[%uD", num); |
196 | else | 245 | return; |
197 | printf("\033[%dD", num); | ||
198 | } else { | ||
199 | /* Need to go one or more lines up */ | ||
200 | int count_y; | ||
201 | |||
202 | //if (cmdedit_x) { | ||
203 | // /* back to first column */ | ||
204 | // putchar('\r'); | ||
205 | // num -= cmdedit_x; | ||
206 | //} | ||
207 | num -= cmdedit_x;// | ||
208 | count_y = 1 + num / cmdedit_termw; | ||
209 | //printf("\033[%dA", count_y); | ||
210 | cmdedit_y -= count_y; | ||
211 | cmdedit_x = cmdedit_termw * count_y - num; | ||
212 | //printf("\033[%dC", cmdedit_x); | ||
213 | /* go to 1st col; go up; go to correct column */ | ||
214 | printf("\r" "\033[%dA" "\033[%dC", count_y, cmdedit_x);// | ||
215 | } | 246 | } |
247 | |||
248 | /* Need to go one or more lines up */ | ||
249 | num -= cmdedit_x; | ||
250 | count_y = 1 + (num / cmdedit_termw); | ||
251 | cmdedit_y -= count_y; | ||
252 | cmdedit_x = cmdedit_termw * count_y - num; | ||
253 | /* go to 1st col; go up; go to correct column */ | ||
254 | printf("\r" "\033[%dA" "\033[%dC", count_y, cmdedit_x); | ||
216 | } | 255 | } |
217 | 256 | ||
218 | static void put_prompt(void) | 257 | static void put_prompt(void) |
@@ -220,6 +259,7 @@ static void put_prompt(void) | |||
220 | out1str(cmdedit_prompt); | 259 | out1str(cmdedit_prompt); |
221 | cmdedit_x = cmdedit_prmt_len; /* count real x terminal position */ | 260 | cmdedit_x = cmdedit_prmt_len; /* count real x terminal position */ |
222 | cursor = 0; | 261 | cursor = 0; |
262 | // Huh? what if cmdedit_prmt_len >= width? | ||
223 | cmdedit_y = 0; /* new quasireal y */ | 263 | cmdedit_y = 0; /* new quasireal y */ |
224 | } | 264 | } |
225 | 265 | ||
@@ -1105,23 +1145,15 @@ static void cmdedit_reset_term(void) | |||
1105 | fflush(stdout); | 1145 | fflush(stdout); |
1106 | } | 1146 | } |
1107 | 1147 | ||
1108 | static void cmdedit_setwidth(int w, int redraw_flg) | 1148 | static void cmdedit_setwidth(unsigned w, int redraw_flg) |
1109 | { | 1149 | { |
1110 | cmdedit_termw = cmdedit_prmt_len + 2; | 1150 | cmdedit_termw = w; |
1111 | if (w <= cmdedit_termw) { | 1151 | if (redraw_flg) { |
1112 | cmdedit_termw = cmdedit_termw % w; | 1152 | /* new y for current cursor */ |
1113 | } | 1153 | int new_y = (cursor + cmdedit_prmt_len) / w; |
1114 | if (w > cmdedit_termw) { | 1154 | /* redraw */ |
1115 | cmdedit_termw = w; | 1155 | redraw((new_y >= cmdedit_y ? new_y : cmdedit_y), len - cursor); |
1116 | 1156 | fflush(stdout); | |
1117 | if (redraw_flg) { | ||
1118 | /* new y for current cursor */ | ||
1119 | int new_y = (cursor + cmdedit_prmt_len) / w; | ||
1120 | |||
1121 | /* redraw */ | ||
1122 | redraw((new_y >= cmdedit_y ? new_y : cmdedit_y), len - cursor); | ||
1123 | fflush(stdout); | ||
1124 | } | ||
1125 | } | 1157 | } |
1126 | } | 1158 | } |
1127 | 1159 | ||
@@ -1310,7 +1342,7 @@ static void parse_prompt(const char *prmt_ptr) | |||
1310 | 1342 | ||
1311 | /* leave out the "vi-mode"-only case labels if vi editing isn't | 1343 | /* leave out the "vi-mode"-only case labels if vi editing isn't |
1312 | * configured. */ | 1344 | * configured. */ |
1313 | #define vi_case(caselabel) USE_FEATURE_COMMAND_EDITING(caselabel) | 1345 | #define vi_case(caselabel) USE_FEATURE_COMMAND_EDITING(case caselabel) |
1314 | 1346 | ||
1315 | /* convert uppercase ascii to equivalent control char, for readability */ | 1347 | /* convert uppercase ascii to equivalent control char, for readability */ |
1316 | #undef CTRL | 1348 | #undef CTRL |
@@ -1328,9 +1360,10 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ]) | |||
1328 | smalluint prevc; | 1360 | smalluint prevc; |
1329 | #endif | 1361 | #endif |
1330 | /* prepare before init handlers */ | 1362 | /* prepare before init handlers */ |
1331 | cmdedit_y = 0; /* quasireal y, not true work if line > xt*yt */ | 1363 | cmdedit_y = 0; /* quasireal y, not true if line > xt*yt */ |
1332 | len = 0; | 1364 | len = 0; |
1333 | command_ps = command; | 1365 | command_ps = command; |
1366 | command[0] = '\0'; | ||
1334 | 1367 | ||
1335 | getTermSettings(0, (void *) &initial_settings); | 1368 | getTermSettings(0, (void *) &initial_settings); |
1336 | memcpy(&new_settings, &initial_settings, sizeof(struct termios)); | 1369 | memcpy(&new_settings, &initial_settings, sizeof(struct termios)); |
@@ -1341,12 +1374,10 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ]) | |||
1341 | new_settings.c_cc[VMIN] = 1; | 1374 | new_settings.c_cc[VMIN] = 1; |
1342 | new_settings.c_cc[VTIME] = 0; | 1375 | new_settings.c_cc[VTIME] = 0; |
1343 | /* Turn off CTRL-C, so we can trap it */ | 1376 | /* Turn off CTRL-C, so we can trap it */ |
1344 | # ifndef _POSIX_VDISABLE | 1377 | #ifndef _POSIX_VDISABLE |
1345 | # define _POSIX_VDISABLE '\0' | 1378 | #define _POSIX_VDISABLE '\0' |
1346 | # endif | 1379 | #endif |
1347 | new_settings.c_cc[VINTR] = _POSIX_VDISABLE; | 1380 | new_settings.c_cc[VINTR] = _POSIX_VDISABLE; |
1348 | command[0] = 0; | ||
1349 | |||
1350 | setTermSettings(0, (void *) &new_settings); | 1381 | setTermSettings(0, (void *) &new_settings); |
1351 | handlers_sets |= SET_RESET_TERM; | 1382 | handlers_sets |= SET_RESET_TERM; |
1352 | 1383 | ||
@@ -1372,30 +1403,30 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ]) | |||
1372 | switch (ic) { | 1403 | switch (ic) { |
1373 | case '\n': | 1404 | case '\n': |
1374 | case '\r': | 1405 | case '\r': |
1375 | vi_case( case '\n'|vbit: ) | 1406 | vi_case('\n'|vbit:) |
1376 | vi_case( case '\r'|vbit: ) | 1407 | vi_case('\r'|vbit:) |
1377 | /* Enter */ | 1408 | /* Enter */ |
1378 | goto_new_line(); | 1409 | goto_new_line(); |
1379 | break_out = 1; | 1410 | break_out = 1; |
1380 | break; | 1411 | break; |
1381 | case CTRL('A'): | 1412 | case CTRL('A'): |
1382 | vi_case( case '0'|vbit: ) | 1413 | vi_case('0'|vbit:) |
1383 | /* Control-a -- Beginning of line */ | 1414 | /* Control-a -- Beginning of line */ |
1384 | input_backward(cursor); | 1415 | input_backward(cursor); |
1385 | break; | 1416 | break; |
1386 | case CTRL('B'): | 1417 | case CTRL('B'): |
1387 | vi_case( case 'h'|vbit: ) | 1418 | vi_case('h'|vbit:) |
1388 | vi_case( case '\b'|vbit: ) | 1419 | vi_case('\b'|vbit:) |
1389 | vi_case( case '\x7f'|vbit: ) /* DEL */ | 1420 | vi_case('\x7f'|vbit:) /* DEL */ |
1390 | /* Control-b -- Move back one character */ | 1421 | /* Control-b -- Move back one character */ |
1391 | input_backward(1); | 1422 | input_backward(1); |
1392 | break; | 1423 | break; |
1393 | case CTRL('C'): | 1424 | case CTRL('C'): |
1394 | vi_case( case CTRL('C')|vbit: ) | 1425 | vi_case(CTRL('C')|vbit:) |
1395 | /* Control-c -- stop gathering input */ | 1426 | /* Control-c -- stop gathering input */ |
1396 | goto_new_line(); | 1427 | goto_new_line(); |
1397 | #if !ENABLE_ASH | 1428 | #if !ENABLE_ASH |
1398 | command[0] = 0; | 1429 | command[0] = '\0'; |
1399 | len = 0; | 1430 | len = 0; |
1400 | lastWasTab = FALSE; | 1431 | lastWasTab = FALSE; |
1401 | put_prompt(); | 1432 | put_prompt(); |
@@ -1427,13 +1458,13 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ]) | |||
1427 | } | 1458 | } |
1428 | break; | 1459 | break; |
1429 | case CTRL('E'): | 1460 | case CTRL('E'): |
1430 | vi_case( case '$'|vbit: ) | 1461 | vi_case('$'|vbit:) |
1431 | /* Control-e -- End of line */ | 1462 | /* Control-e -- End of line */ |
1432 | input_end(); | 1463 | input_end(); |
1433 | break; | 1464 | break; |
1434 | case CTRL('F'): | 1465 | case CTRL('F'): |
1435 | vi_case( case 'l'|vbit: ) | 1466 | vi_case('l'|vbit:) |
1436 | vi_case( case ' '|vbit: ) | 1467 | vi_case(' '|vbit:) |
1437 | /* Control-f -- Move forward one character */ | 1468 | /* Control-f -- Move forward one character */ |
1438 | input_forward(); | 1469 | input_forward(); |
1439 | break; | 1470 | break; |
@@ -1454,22 +1485,22 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ]) | |||
1454 | printf("\033[J"); | 1485 | printf("\033[J"); |
1455 | break; | 1486 | break; |
1456 | case CTRL('L'): | 1487 | case CTRL('L'): |
1457 | vi_case( case CTRL('L')|vbit: ) | 1488 | vi_case(CTRL('L')|vbit:) |
1458 | /* Control-l -- clear screen */ | 1489 | /* Control-l -- clear screen */ |
1459 | printf("\033[H"); | 1490 | printf("\033[H"); |
1460 | redraw(0, len - cursor); | 1491 | redraw(0, len - cursor); |
1461 | break; | 1492 | break; |
1462 | #if MAX_HISTORY > 0 | 1493 | #if MAX_HISTORY > 0 |
1463 | case CTRL('N'): | 1494 | case CTRL('N'): |
1464 | vi_case( case CTRL('N')|vbit: ) | 1495 | vi_case(CTRL('N')|vbit:) |
1465 | vi_case( case 'j'|vbit: ) | 1496 | vi_case('j'|vbit:) |
1466 | /* Control-n -- Get next command in history */ | 1497 | /* Control-n -- Get next command in history */ |
1467 | if (get_next_history()) | 1498 | if (get_next_history()) |
1468 | goto rewrite_line; | 1499 | goto rewrite_line; |
1469 | break; | 1500 | break; |
1470 | case CTRL('P'): | 1501 | case CTRL('P'): |
1471 | vi_case( case CTRL('P')|vbit: ) | 1502 | vi_case(CTRL('P')|vbit:) |
1472 | vi_case( case 'k'|vbit: ) | 1503 | vi_case('k'|vbit:) |
1473 | /* Control-p -- Get previous command from history */ | 1504 | /* Control-p -- Get previous command from history */ |
1474 | if (cur_history > 0) { | 1505 | if (cur_history > 0) { |
1475 | get_previous_history(); | 1506 | get_previous_history(); |
@@ -1480,7 +1511,7 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ]) | |||
1480 | break; | 1511 | break; |
1481 | #endif | 1512 | #endif |
1482 | case CTRL('U'): | 1513 | case CTRL('U'): |
1483 | vi_case( case CTRL('U')|vbit: ) | 1514 | vi_case(CTRL('U')|vbit:) |
1484 | /* Control-U -- Clear line before cursor */ | 1515 | /* Control-U -- Clear line before cursor */ |
1485 | if (cursor) { | 1516 | if (cursor) { |
1486 | strcpy(command, command + cursor); | 1517 | strcpy(command, command + cursor); |
@@ -1488,7 +1519,7 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ]) | |||
1488 | } | 1519 | } |
1489 | break; | 1520 | break; |
1490 | case CTRL('W'): | 1521 | case CTRL('W'): |
1491 | vi_case( case CTRL('W')|vbit: ) | 1522 | vi_case(CTRL('W')|vbit:) |
1492 | /* Control-W -- Remove the last word */ | 1523 | /* Control-W -- Remove the last word */ |
1493 | while (cursor > 0 && isspace(command[cursor-1])) | 1524 | while (cursor > 0 && isspace(command[cursor-1])) |
1494 | input_backspace(); | 1525 | input_backspace(); |
@@ -1639,8 +1670,8 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ]) | |||
1639 | goto prepare_to_die; | 1670 | goto prepare_to_die; |
1640 | /* different vt100 emulations */ | 1671 | /* different vt100 emulations */ |
1641 | if (c == '[' || c == 'O') { | 1672 | if (c == '[' || c == 'O') { |
1642 | vi_case( case '['|vbit: ) | 1673 | vi_case('['|vbit:) |
1643 | vi_case( case 'O'|vbit: ) | 1674 | vi_case('O'|vbit:) |
1644 | if (safe_read(0, &c, 1) < 1) | 1675 | if (safe_read(0, &c, 1) < 1) |
1645 | goto prepare_to_die; | 1676 | goto prepare_to_die; |
1646 | } | 1677 | } |
@@ -1650,7 +1681,7 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ]) | |||
1650 | if (safe_read(0, &dummy, 1) < 1) | 1681 | if (safe_read(0, &dummy, 1) < 1) |
1651 | goto prepare_to_die; | 1682 | goto prepare_to_die; |
1652 | if (dummy != '~') | 1683 | if (dummy != '~') |
1653 | c = 0; | 1684 | c = '\0'; |
1654 | } | 1685 | } |
1655 | switch (c) { | 1686 | switch (c) { |
1656 | #if ENABLE_FEATURE_COMMAND_TAB_COMPLETION | 1687 | #if ENABLE_FEATURE_COMMAND_TAB_COMPLETION |
@@ -1671,8 +1702,8 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ]) | |||
1671 | /* Down Arrow -- Get next command in history */ | 1702 | /* Down Arrow -- Get next command in history */ |
1672 | if (!get_next_history()) | 1703 | if (!get_next_history()) |
1673 | break; | 1704 | break; |
1674 | /* Rewrite the line with the selected history item */ | ||
1675 | rewrite_line: | 1705 | rewrite_line: |
1706 | /* Rewrite the line with the selected history item */ | ||
1676 | /* change command */ | 1707 | /* change command */ |
1677 | len = strlen(strcpy(command, history[cur_history])); | 1708 | len = strlen(strcpy(command, history[cur_history])); |
1678 | /* redraw and go to eol (bol, in vi */ | 1709 | /* redraw and go to eol (bol, in vi */ |