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
*/
/*
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 "busybox.h"
#include "cmdedit.h"
@ -86,7 +131,7 @@ enum {
static int cmdedit_x; /* real x 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 len;
@ -179,40 +224,34 @@ static void beep(void)
}
/* Move back one character */
/* special for slow terminal */
static void input_backward(int num)
/* (optimized for slow terminals) */
static void input_backward(unsigned num)
{
int count_y;
if (num > cursor)
num = cursor;
cursor -= num; /* new cursor (in command, not terminal) */
if (!num)
return;
cursor -= num;
if (cmdedit_x >= num) {
cmdedit_x -= num;
if (num <= 4)
while (num > 0) {
putchar('\b');
num--;
}
else
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);//
if (num <= 4) {
do putchar('\b'); while (--num);
return;
}
printf("\033[%uD", num);
return;
}
/* 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)
@ -220,6 +259,7 @@ static void put_prompt(void)
out1str(cmdedit_prompt);
cmdedit_x = cmdedit_prmt_len; /* count real x terminal position */
cursor = 0;
// Huh? what if cmdedit_prmt_len >= width?
cmdedit_y = 0; /* new quasireal y */
}
@ -1105,23 +1145,15 @@ static void cmdedit_reset_term(void)
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;
if (w <= cmdedit_termw) {
cmdedit_termw = cmdedit_termw % w;
}
if (w > cmdedit_termw) {
cmdedit_termw = w;
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);
}
cmdedit_termw = w;
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
* 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 */
#undef CTRL
@ -1328,9 +1360,10 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ])
smalluint prevc;
#endif
/* 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;
command_ps = command;
command[0] = '\0';
getTermSettings(0, (void *) &initial_settings);
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[VTIME] = 0;
/* Turn off CTRL-C, so we can trap it */
# ifndef _POSIX_VDISABLE
# define _POSIX_VDISABLE '\0'
# endif
#ifndef _POSIX_VDISABLE
#define _POSIX_VDISABLE '\0'
#endif
new_settings.c_cc[VINTR] = _POSIX_VDISABLE;
command[0] = 0;
setTermSettings(0, (void *) &new_settings);
handlers_sets |= SET_RESET_TERM;
@ -1372,30 +1403,30 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ])
switch (ic) {
case '\n':
case '\r':
vi_case( case '\n'|vbit: )
vi_case( case '\r'|vbit: )
vi_case('\n'|vbit:)
vi_case('\r'|vbit:)
/* Enter */
goto_new_line();
break_out = 1;
break;
case CTRL('A'):
vi_case( case '0'|vbit: )
vi_case('0'|vbit:)
/* Control-a -- Beginning of line */
input_backward(cursor);
break;
case CTRL('B'):
vi_case( case 'h'|vbit: )
vi_case( case '\b'|vbit: )
vi_case( case '\x7f'|vbit: ) /* DEL */
vi_case('h'|vbit:)
vi_case('\b'|vbit:)
vi_case('\x7f'|vbit:) /* DEL */
/* Control-b -- Move back one character */
input_backward(1);
break;
case CTRL('C'):
vi_case( case CTRL('C')|vbit: )
vi_case(CTRL('C')|vbit:)
/* Control-c -- stop gathering input */
goto_new_line();
#if !ENABLE_ASH
command[0] = 0;
command[0] = '\0';
len = 0;
lastWasTab = FALSE;
put_prompt();
@ -1427,13 +1458,13 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ])
}
break;
case CTRL('E'):
vi_case( case '$'|vbit: )
vi_case('$'|vbit:)
/* Control-e -- End of line */
input_end();
break;
case CTRL('F'):
vi_case( case 'l'|vbit: )
vi_case( case ' '|vbit: )
vi_case('l'|vbit:)
vi_case(' '|vbit:)
/* Control-f -- Move forward one character */
input_forward();
break;
@ -1454,22 +1485,22 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ])
printf("\033[J");
break;
case CTRL('L'):
vi_case( case CTRL('L')|vbit: )
vi_case(CTRL('L')|vbit:)
/* Control-l -- clear screen */
printf("\033[H");
redraw(0, len - cursor);
break;
#if MAX_HISTORY > 0
case CTRL('N'):
vi_case( case CTRL('N')|vbit: )
vi_case( case 'j'|vbit: )
vi_case(CTRL('N')|vbit:)
vi_case('j'|vbit:)
/* Control-n -- Get next command in history */
if (get_next_history())
goto rewrite_line;
break;
case CTRL('P'):
vi_case( case CTRL('P')|vbit: )
vi_case( case 'k'|vbit: )
vi_case(CTRL('P')|vbit:)
vi_case('k'|vbit:)
/* Control-p -- Get previous command from history */
if (cur_history > 0) {
get_previous_history();
@ -1480,7 +1511,7 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ])
break;
#endif
case CTRL('U'):
vi_case( case CTRL('U')|vbit: )
vi_case(CTRL('U')|vbit:)
/* Control-U -- Clear line before cursor */
if (cursor) {
strcpy(command, command + cursor);
@ -1488,7 +1519,7 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ])
}
break;
case CTRL('W'):
vi_case( case CTRL('W')|vbit: )
vi_case(CTRL('W')|vbit:)
/* Control-W -- Remove the last word */
while (cursor > 0 && isspace(command[cursor-1]))
input_backspace();
@ -1639,8 +1670,8 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ])
goto prepare_to_die;
/* different vt100 emulations */
if (c == '[' || c == 'O') {
vi_case( case '['|vbit: )
vi_case( case 'O'|vbit: )
vi_case('['|vbit:)
vi_case('O'|vbit:)
if (safe_read(0, &c, 1) < 1)
goto prepare_to_die;
}
@ -1650,7 +1681,7 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ])
if (safe_read(0, &dummy, 1) < 1)
goto prepare_to_die;
if (dummy != '~')
c = 0;
c = '\0';
}
switch (c) {
#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 */
if (!get_next_history())
break;
/* Rewrite the line with the selected history item */
rewrite_line:
/* Rewrite the line with the selected history item */
/* change command */
len = strlen(strcpy(command, history[cur_history]));
/* redraw and go to eol (bol, in vi */