summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-01-21 19:18:59 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-01-21 19:18:59 +0000
commit47bdb3ac482e8ccfa073b1c17fdf52d3721952b6 (patch)
treec1b572a5d0e3a9a30ca9011a16aad9bb0633a201
parent82b39e83ab13660f0b76a52519e1ac44e30fff7c (diff)
downloadbusybox-w32-47bdb3ac482e8ccfa073b1c17fdf52d3721952b6.tar.gz
busybox-w32-47bdb3ac482e8ccfa073b1c17fdf52d3721952b6.tar.bz2
busybox-w32-47bdb3ac482e8ccfa073b1c17fdf52d3721952b6.zip
cmdedit: small optimizations
-rw-r--r--shell/cmdedit.c177
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/*
32CONFIG_FEATURE_COMMAND_EDITING=y
33# CONFIG_FEATURE_COMMAND_EDITING_VI is not set
34CONFIG_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
39Sizes 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
4400000004 b cmdedit_prmt_len
4500000004 b cmdedit_prompt
4600000004 d cmdedit_termw
4700000004 b cmdedit_x
4800000004 b cmdedit_y
4900000004 b command_ps
5000000004 b cur_history
5100000004 b cursor
5200000004 b handlers_sets
5300000004 b len
5400000004 b n_history
5500000004 b previous_SIGWINCH_handler
5600000009 t beep
5700000017 t goto_new_line
580000001a t input_end
590000001b t input_backspace
600000001e t input_forward
6100000027 t get_next_history
6200000036 t put_prompt
6300000039 t redraw
640000003c b initial_settings
650000003c b new_settings
6600000040 b history
6700000047 t input_delete
680000004d t get_previous_history
6900000059 t cmdedit_reset_term
700000006c t cmdedit_set_out_char
7100000087 t input_backward
72000000a1 t win_changed
730000053c 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
87static int cmdedit_x; /* real x terminal position */ 132static int cmdedit_x; /* real x terminal position */
88static int cmdedit_y; /* pseudoreal y terminal position */ 133static int cmdedit_y; /* pseudoreal y terminal position */
89static int cmdedit_prmt_len; /* length of prompt without colores string */ 134static int cmdedit_prmt_len; /* length of prompt (without colors etc) */
90 135
91static int cursor; 136static int cursor;
92static int len; 137static 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) */
183static void input_backward(int num) 228static 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
218static void put_prompt(void) 257static 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
1108static void cmdedit_setwidth(int w, int redraw_flg) 1148static 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 */