cmdedit: small optimizations

This commit is contained in:
Denis Vlasenko 2007-01-21 19:18:59 +00:00
parent 82b39e83ab
commit 47bdb3ac48

View File

@ -28,6 +28,51 @@
- not true viewing if length prompt less terminal width - not true viewing if length prompt less terminal width
*/ */
/*
CONFIG_FEATURE_COMMAND_EDITING=y
# CONFIG_FEATURE_COMMAND_EDITING_VI is not set
CONFIG_FEATURE_COMMAND_HISTORY=15
# CONFIG_FEATURE_COMMAND_SAVEHISTORY is not set
# CONFIG_FEATURE_COMMAND_TAB_COMPLETION is not set
# CONFIG_FEATURE_COMMAND_USERNAME_COMPLETION is not set
# CONFIG_FEATURE_SH_FANCY_PROMPT is not set
Sizes with the above:
# size cmdedit.o
text data bss dec hex filename
2374 4 228 2606 a2e cmdedit.o
# nm --size-sort cmdedit.o
00000004 b cmdedit_prmt_len
00000004 b cmdedit_prompt
00000004 d cmdedit_termw
00000004 b cmdedit_x
00000004 b cmdedit_y
00000004 b command_ps
00000004 b cur_history
00000004 b cursor
00000004 b handlers_sets
00000004 b len
00000004 b n_history
00000004 b previous_SIGWINCH_handler
00000009 t beep
00000017 t goto_new_line
0000001a t input_end
0000001b t input_backspace
0000001e t input_forward
00000027 t get_next_history
00000036 t put_prompt
00000039 t redraw
0000003c b initial_settings
0000003c b new_settings
00000040 b history
00000047 t input_delete
0000004d t get_previous_history
00000059 t cmdedit_reset_term
0000006c t cmdedit_set_out_char
00000087 t input_backward
000000a1 t win_changed
0000053c T cmdedit_read_input
*/
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include "busybox.h" #include "busybox.h"
#include "cmdedit.h" #include "cmdedit.h"
@ -86,7 +131,7 @@ enum {
static int cmdedit_x; /* real x terminal position */ static int cmdedit_x; /* real x terminal position */
static int cmdedit_y; /* pseudoreal y terminal position */ static int cmdedit_y; /* pseudoreal y terminal position */
static int cmdedit_prmt_len; /* length of prompt without colores string */ static int cmdedit_prmt_len; /* length of prompt (without colors etc) */
static int cursor; static int cursor;
static int len; static int len;
@ -179,40 +224,34 @@ static void beep(void)
} }
/* Move back one character */ /* Move back one character */
/* special for slow terminal */ /* (optimized for slow terminals) */
static void input_backward(int num) static void input_backward(unsigned num)
{ {
int count_y;
if (num > cursor) if (num > cursor)
num = cursor; num = cursor;
cursor -= num; /* new cursor (in command, not terminal) */ if (!num)
return;
cursor -= num;
if (cmdedit_x >= num) { if (cmdedit_x >= num) {
cmdedit_x -= num; cmdedit_x -= num;
if (num <= 4) if (num <= 4) {
while (num > 0) { do putchar('\b'); while (--num);
putchar('\b'); return;
num--; }
} printf("\033[%uD", num);
else return;
printf("\033[%dD", num);
} else {
/* Need to go one or more lines up */
int count_y;
//if (cmdedit_x) {
// /* back to first column */
// putchar('\r');
// num -= cmdedit_x;
//}
num -= cmdedit_x;//
count_y = 1 + num / cmdedit_termw;
//printf("\033[%dA", count_y);
cmdedit_y -= count_y;
cmdedit_x = cmdedit_termw * count_y - num;
//printf("\033[%dC", cmdedit_x);
/* go to 1st col; go up; go to correct column */
printf("\r" "\033[%dA" "\033[%dC", count_y, cmdedit_x);//
} }
/* Need to go one or more lines up */
num -= cmdedit_x;
count_y = 1 + (num / cmdedit_termw);
cmdedit_y -= count_y;
cmdedit_x = cmdedit_termw * count_y - num;
/* go to 1st col; go up; go to correct column */
printf("\r" "\033[%dA" "\033[%dC", count_y, cmdedit_x);
} }
static void put_prompt(void) static void put_prompt(void)
@ -220,6 +259,7 @@ static void put_prompt(void)
out1str(cmdedit_prompt); out1str(cmdedit_prompt);
cmdedit_x = cmdedit_prmt_len; /* count real x terminal position */ cmdedit_x = cmdedit_prmt_len; /* count real x terminal position */
cursor = 0; cursor = 0;
// Huh? what if cmdedit_prmt_len >= width?
cmdedit_y = 0; /* new quasireal y */ cmdedit_y = 0; /* new quasireal y */
} }
@ -1105,23 +1145,15 @@ static void cmdedit_reset_term(void)
fflush(stdout); fflush(stdout);
} }
static void cmdedit_setwidth(int w, int redraw_flg) static void cmdedit_setwidth(unsigned w, int redraw_flg)
{ {
cmdedit_termw = cmdedit_prmt_len + 2; cmdedit_termw = w;
if (w <= cmdedit_termw) { if (redraw_flg) {
cmdedit_termw = cmdedit_termw % w; /* new y for current cursor */
} int new_y = (cursor + cmdedit_prmt_len) / w;
if (w > cmdedit_termw) { /* redraw */
cmdedit_termw = w; redraw((new_y >= cmdedit_y ? new_y : cmdedit_y), len - cursor);
fflush(stdout);
if (redraw_flg) {
/* new y for current cursor */
int new_y = (cursor + cmdedit_prmt_len) / w;
/* redraw */
redraw((new_y >= cmdedit_y ? new_y : cmdedit_y), len - cursor);
fflush(stdout);
}
} }
} }
@ -1310,7 +1342,7 @@ static void parse_prompt(const char *prmt_ptr)
/* leave out the "vi-mode"-only case labels if vi editing isn't /* leave out the "vi-mode"-only case labels if vi editing isn't
* configured. */ * configured. */
#define vi_case(caselabel) USE_FEATURE_COMMAND_EDITING(caselabel) #define vi_case(caselabel) USE_FEATURE_COMMAND_EDITING(case caselabel)
/* convert uppercase ascii to equivalent control char, for readability */ /* convert uppercase ascii to equivalent control char, for readability */
#undef CTRL #undef CTRL
@ -1328,9 +1360,10 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ])
smalluint prevc; smalluint prevc;
#endif #endif
/* prepare before init handlers */ /* prepare before init handlers */
cmdedit_y = 0; /* quasireal y, not true work if line > xt*yt */ cmdedit_y = 0; /* quasireal y, not true if line > xt*yt */
len = 0; len = 0;
command_ps = command; command_ps = command;
command[0] = '\0';
getTermSettings(0, (void *) &initial_settings); getTermSettings(0, (void *) &initial_settings);
memcpy(&new_settings, &initial_settings, sizeof(struct termios)); memcpy(&new_settings, &initial_settings, sizeof(struct termios));
@ -1341,12 +1374,10 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ])
new_settings.c_cc[VMIN] = 1; new_settings.c_cc[VMIN] = 1;
new_settings.c_cc[VTIME] = 0; new_settings.c_cc[VTIME] = 0;
/* Turn off CTRL-C, so we can trap it */ /* Turn off CTRL-C, so we can trap it */
# ifndef _POSIX_VDISABLE #ifndef _POSIX_VDISABLE
# define _POSIX_VDISABLE '\0' #define _POSIX_VDISABLE '\0'
# endif #endif
new_settings.c_cc[VINTR] = _POSIX_VDISABLE; new_settings.c_cc[VINTR] = _POSIX_VDISABLE;
command[0] = 0;
setTermSettings(0, (void *) &new_settings); setTermSettings(0, (void *) &new_settings);
handlers_sets |= SET_RESET_TERM; handlers_sets |= SET_RESET_TERM;
@ -1372,30 +1403,30 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ])
switch (ic) { switch (ic) {
case '\n': case '\n':
case '\r': case '\r':
vi_case( case '\n'|vbit: ) vi_case('\n'|vbit:)
vi_case( case '\r'|vbit: ) vi_case('\r'|vbit:)
/* Enter */ /* Enter */
goto_new_line(); goto_new_line();
break_out = 1; break_out = 1;
break; break;
case CTRL('A'): case CTRL('A'):
vi_case( case '0'|vbit: ) vi_case('0'|vbit:)
/* Control-a -- Beginning of line */ /* Control-a -- Beginning of line */
input_backward(cursor); input_backward(cursor);
break; break;
case CTRL('B'): case CTRL('B'):
vi_case( case 'h'|vbit: ) vi_case('h'|vbit:)
vi_case( case '\b'|vbit: ) vi_case('\b'|vbit:)
vi_case( case '\x7f'|vbit: ) /* DEL */ vi_case('\x7f'|vbit:) /* DEL */
/* Control-b -- Move back one character */ /* Control-b -- Move back one character */
input_backward(1); input_backward(1);
break; break;
case CTRL('C'): case CTRL('C'):
vi_case( case CTRL('C')|vbit: ) vi_case(CTRL('C')|vbit:)
/* Control-c -- stop gathering input */ /* Control-c -- stop gathering input */
goto_new_line(); goto_new_line();
#if !ENABLE_ASH #if !ENABLE_ASH
command[0] = 0; command[0] = '\0';
len = 0; len = 0;
lastWasTab = FALSE; lastWasTab = FALSE;
put_prompt(); put_prompt();
@ -1427,13 +1458,13 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ])
} }
break; break;
case CTRL('E'): case CTRL('E'):
vi_case( case '$'|vbit: ) vi_case('$'|vbit:)
/* Control-e -- End of line */ /* Control-e -- End of line */
input_end(); input_end();
break; break;
case CTRL('F'): case CTRL('F'):
vi_case( case 'l'|vbit: ) vi_case('l'|vbit:)
vi_case( case ' '|vbit: ) vi_case(' '|vbit:)
/* Control-f -- Move forward one character */ /* Control-f -- Move forward one character */
input_forward(); input_forward();
break; break;
@ -1454,22 +1485,22 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ])
printf("\033[J"); printf("\033[J");
break; break;
case CTRL('L'): case CTRL('L'):
vi_case( case CTRL('L')|vbit: ) vi_case(CTRL('L')|vbit:)
/* Control-l -- clear screen */ /* Control-l -- clear screen */
printf("\033[H"); printf("\033[H");
redraw(0, len - cursor); redraw(0, len - cursor);
break; break;
#if MAX_HISTORY > 0 #if MAX_HISTORY > 0
case CTRL('N'): case CTRL('N'):
vi_case( case CTRL('N')|vbit: ) vi_case(CTRL('N')|vbit:)
vi_case( case 'j'|vbit: ) vi_case('j'|vbit:)
/* Control-n -- Get next command in history */ /* Control-n -- Get next command in history */
if (get_next_history()) if (get_next_history())
goto rewrite_line; goto rewrite_line;
break; break;
case CTRL('P'): case CTRL('P'):
vi_case( case CTRL('P')|vbit: ) vi_case(CTRL('P')|vbit:)
vi_case( case 'k'|vbit: ) vi_case('k'|vbit:)
/* Control-p -- Get previous command from history */ /* Control-p -- Get previous command from history */
if (cur_history > 0) { if (cur_history > 0) {
get_previous_history(); get_previous_history();
@ -1480,7 +1511,7 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ])
break; break;
#endif #endif
case CTRL('U'): case CTRL('U'):
vi_case( case CTRL('U')|vbit: ) vi_case(CTRL('U')|vbit:)
/* Control-U -- Clear line before cursor */ /* Control-U -- Clear line before cursor */
if (cursor) { if (cursor) {
strcpy(command, command + cursor); strcpy(command, command + cursor);
@ -1488,7 +1519,7 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ])
} }
break; break;
case CTRL('W'): case CTRL('W'):
vi_case( case CTRL('W')|vbit: ) vi_case(CTRL('W')|vbit:)
/* Control-W -- Remove the last word */ /* Control-W -- Remove the last word */
while (cursor > 0 && isspace(command[cursor-1])) while (cursor > 0 && isspace(command[cursor-1]))
input_backspace(); input_backspace();
@ -1639,8 +1670,8 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ])
goto prepare_to_die; goto prepare_to_die;
/* different vt100 emulations */ /* different vt100 emulations */
if (c == '[' || c == 'O') { if (c == '[' || c == 'O') {
vi_case( case '['|vbit: ) vi_case('['|vbit:)
vi_case( case 'O'|vbit: ) vi_case('O'|vbit:)
if (safe_read(0, &c, 1) < 1) if (safe_read(0, &c, 1) < 1)
goto prepare_to_die; goto prepare_to_die;
} }
@ -1650,7 +1681,7 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ])
if (safe_read(0, &dummy, 1) < 1) if (safe_read(0, &dummy, 1) < 1)
goto prepare_to_die; goto prepare_to_die;
if (dummy != '~') if (dummy != '~')
c = 0; c = '\0';
} }
switch (c) { switch (c) {
#if ENABLE_FEATURE_COMMAND_TAB_COMPLETION #if ENABLE_FEATURE_COMMAND_TAB_COMPLETION
@ -1671,8 +1702,8 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ])
/* Down Arrow -- Get next command in history */ /* Down Arrow -- Get next command in history */
if (!get_next_history()) if (!get_next_history())
break; break;
/* Rewrite the line with the selected history item */
rewrite_line: rewrite_line:
/* Rewrite the line with the selected history item */
/* change command */ /* change command */
len = strlen(strcpy(command, history[cur_history])); len = strlen(strcpy(command, history[cur_history]));
/* redraw and go to eol (bol, in vi */ /* redraw and go to eol (bol, in vi */