vi: nuke FEATURE_VI_OPTIMIZE_CURSOR

It is not Unicode safe, it is not saving much of I/O, and it's large:

function                                             old     new   delta
vi_main                                              255     253      -2
go_bottom_and_clear_to_eol                            28      26      -2
do_cmd                                              4194    4182     -12
show_status_line                                     388     374     -14
strncat                                               39       -     -39
__GI_strncat                                          39       -     -39
refresh                                              774     724     -50
place_cursor                                         276      83    -193
------------------------------------------------------------------------------
(add/remove: 0/3 grow/shrink: 0/6 up/down: 0/-351)           Total: -351 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko
2012-06-11 13:51:38 +02:00
parent 4125a6b630
commit 04b52892ed

View File

@@ -136,14 +136,6 @@
//config: cursor position using "ESC [ 6 n" escape sequence, then read stdin. //config: cursor position using "ESC [ 6 n" escape sequence, then read stdin.
//config: //config:
//config: This is not clean but helps a lot on serial lines and such. //config: This is not clean but helps a lot on serial lines and such.
//config:
//config:config FEATURE_VI_OPTIMIZE_CURSOR
//config: bool "Optimize cursor movement"
//config: default y
//config: depends on VI
//config: help
//config: This will make the cursor movement faster, but requires more memory
//config: and it makes the applet a tiny bit larger.
//applet:IF_VI(APPLET(vi, BB_DIR_BIN, BB_SUID_DROP)) //applet:IF_VI(APPLET(vi, BB_DIR_BIN, BB_SUID_DROP))
@@ -202,20 +194,29 @@ enum {
MAX_SCR_ROWS = CONFIG_FEATURE_VI_MAX_LEN, MAX_SCR_ROWS = CONFIG_FEATURE_VI_MAX_LEN,
}; };
/* vt102 typical ESC sequence */ /* VT102 ESC sequences.
/* terminal standout start/normal ESC sequence */ * See "Xterm Control Sequences"
#define SOs "\033[7m" * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html
#define SOn "\033[0m" */
/* terminal bell sequence */ /* Inverse/Normal text */
#define bell "\007" #define ESC_BOLD_TEXT "\033[7m"
/* Clear-end-of-line and Clear-end-of-screen ESC sequence */ #define ESC_NORM_TEXT "\033[0m"
#define Ceol "\033[K" /* Bell */
#define Ceos "\033[J" #define ESC_BELL "\007"
/* Cursor motion arbitrary destination ESC sequence */ /* Clear-to-end-of-line */
#define CMrc "\033[%u;%uH" #define ESC_CLEAR2EOL "\033[K"
/* Cursor motion up and down ESC sequence */ /* Clear-to-end-of-screen.
#define CMup "\033[A" * (We use default param here.
#define CMdown "\n" * Full sequence is "ESC [ <num> J",
* <num> is 0/1/2 = "erase below/above/all".)
*/
#define ESC_CLEAR2EOS "\033[J"
/* Cursor to given coordinate (1,1: top left) */
#define ESC_SET_CURSOR_POS "\033[%u;%uH"
//UNUSED
///* Cursor up and down */
//#define ESC_CURSOR_UP "\033[A"
//#define ESC_CURSOR_DOWN "\n"
#if ENABLE_FEATURE_VI_DOT_CMD || ENABLE_FEATURE_VI_YANKMARK #if ENABLE_FEATURE_VI_DOT_CMD || ENABLE_FEATURE_VI_YANKMARK
// cmds modifying text[] // cmds modifying text[]
@@ -303,9 +304,6 @@ struct globals {
int lmc_len; // length of last_modifying_cmd int lmc_len; // length of last_modifying_cmd
char *ioq, *ioq_start; // pointer to string for get_one_char to "read" char *ioq, *ioq_start; // pointer to string for get_one_char to "read"
#endif #endif
#if ENABLE_FEATURE_VI_OPTIMIZE_CURSOR
int last_row; // where the cursor was last moved to
#endif
#if ENABLE_FEATURE_VI_USE_SIGNALS || ENABLE_FEATURE_VI_CRASHME #if ENABLE_FEATURE_VI_USE_SIGNALS || ENABLE_FEATURE_VI_CRASHME
int my_pid; int my_pid;
#endif #endif
@@ -389,7 +387,6 @@ struct globals {
#define lmc_len (G.lmc_len ) #define lmc_len (G.lmc_len )
#define ioq (G.ioq ) #define ioq (G.ioq )
#define ioq_start (G.ioq_start ) #define ioq_start (G.ioq_start )
#define last_row (G.last_row )
#define my_pid (G.my_pid ) #define my_pid (G.my_pid )
#define last_search_pattern (G.last_search_pattern) #define last_search_pattern (G.last_search_pattern)
@@ -470,10 +467,7 @@ static int file_size(const char *); // what is the byte size of "fn"
// file_insert might reallocate text[]! // file_insert might reallocate text[]!
static int file_insert(const char *, char *, int); static int file_insert(const char *, char *, int);
static int file_write(char *, char *, char *); static int file_write(char *, char *, char *);
#if !ENABLE_FEATURE_VI_OPTIMIZE_CURSOR static void place_cursor(int, int);
#define place_cursor(a, b, optimize) place_cursor(a, b)
#endif
static void place_cursor(int, int, int);
static void screen_erase(void); static void screen_erase(void);
static void clear_to_eol(void); static void clear_to_eol(void);
static void clear_to_eos(void); static void clear_to_eos(void);
@@ -600,10 +594,10 @@ int vi_main(int argc, char **argv)
// The argv array can be used by the ":next" and ":rewind" commands // The argv array can be used by the ":next" and ":rewind" commands
argv += optind; argv += optind;
argc -= optind; argc -= optind;
save_argc = argc;
optind = 0;
//----- This is the main file handling loop -------------- //----- This is the main file handling loop --------------
save_argc = argc;
optind = 0;
while (1) { while (1) {
edit_file(argv[optind]); /* param might be NULL */ edit_file(argv[optind]); /* param might be NULL */
if (++optind >= argc) if (++optind >= argc)
@@ -2593,107 +2587,56 @@ static int file_write(char *fn, char *first, char *last)
// 23,0 ... 23,79 <- status line // 23,0 ... 23,79 <- status line
//----- Move the cursor to row x col (count from 0, not 1) ------- //----- Move the cursor to row x col (count from 0, not 1) -------
static void place_cursor(int row, int col, int optimize) static void place_cursor(int row, int col)
{ {
char cm1[sizeof(CMrc) + sizeof(int)*3 * 2]; char cm1[sizeof(ESC_SET_CURSOR_POS) + sizeof(int)*3 * 2];
#if ENABLE_FEATURE_VI_OPTIMIZE_CURSOR
enum {
SZ_UP = sizeof(CMup),
SZ_DN = sizeof(CMdown),
SEQ_SIZE = SZ_UP > SZ_DN ? SZ_UP : SZ_DN,
};
char cm2[SEQ_SIZE * 5 + 32]; // bigger than worst case size
#endif
char *cm;
if (row < 0) row = 0; if (row < 0) row = 0;
if (row >= rows) row = rows - 1; if (row >= rows) row = rows - 1;
if (col < 0) col = 0; if (col < 0) col = 0;
if (col >= columns) col = columns - 1; if (col >= columns) col = columns - 1;
//----- 1. Try the standard terminal ESC sequence sprintf(cm1, ESC_SET_CURSOR_POS, row + 1, col + 1);
sprintf(cm1, CMrc, row + 1, col + 1); write1(cm1);
cm = cm1;
#if ENABLE_FEATURE_VI_OPTIMIZE_CURSOR
if (optimize && col < 16) {
char *screenp;
int Rrow = last_row;
int diff = Rrow - row;
if (diff < -5 || diff > 5)
goto skip;
//----- find the minimum # of chars to move cursor -------------
//----- 2. Try moving with discreet chars (Newline, [back]space, ...)
cm2[0] = '\0';
// move to the correct row
while (row < Rrow) {
// the cursor has to move up
strcat(cm2, CMup);
Rrow--;
}
while (row > Rrow) {
// the cursor has to move down
strcat(cm2, CMdown);
Rrow++;
}
// now move to the correct column
strcat(cm2, "\r"); // start at col 0
// just send out orignal source char to get to correct place
screenp = &screen[row * columns]; // start of screen line
strncat(cm2, screenp, col);
// pick the shortest cursor motion to send out
if (strlen(cm2) < strlen(cm)) {
cm = cm2;
}
skip: ;
}
last_row = row;
#endif /* FEATURE_VI_OPTIMIZE_CURSOR */
write1(cm);
} }
//----- Erase from cursor to end of line ----------------------- //----- Erase from cursor to end of line -----------------------
static void clear_to_eol(void) static void clear_to_eol(void)
{ {
write1(Ceol); // Erase from cursor to end of line write1(ESC_CLEAR2EOL);
} }
static void go_bottom_and_clear_to_eol(void) static void go_bottom_and_clear_to_eol(void)
{ {
place_cursor(rows - 1, 0, FALSE); // go to bottom of screen place_cursor(rows - 1, 0);
clear_to_eol(); // erase to end of line clear_to_eol();
} }
//----- Erase from cursor to end of screen ----------------------- //----- Erase from cursor to end of screen -----------------------
static void clear_to_eos(void) static void clear_to_eos(void)
{ {
write1(Ceos); // Erase from cursor to end of screen write1(ESC_CLEAR2EOS);
} }
//----- Start standout mode ------------------------------------ //----- Start standout mode ------------------------------------
static void standout_start(void) // send "start reverse video" sequence static void standout_start(void)
{ {
write1(SOs); // Start reverse video mode write1(ESC_BOLD_TEXT);
} }
//----- End standout mode -------------------------------------- //----- End standout mode --------------------------------------
static void standout_end(void) // send "end reverse video" sequence static void standout_end(void)
{ {
write1(SOn); // End reverse video mode write1(ESC_NORM_TEXT);
} }
//----- Flash the screen -------------------------------------- //----- Flash the screen --------------------------------------
static void flash(int h) static void flash(int h)
{ {
standout_start(); // send "start reverse video" sequence standout_start();
redraw(TRUE); redraw(TRUE);
mysleep(h); mysleep(h);
standout_end(); // send "end reverse video" sequence standout_end();
redraw(TRUE); redraw(TRUE);
} }
@@ -2704,7 +2647,7 @@ static void Indicate_Error(void)
return; // generate a random command return; // generate a random command
#endif #endif
if (!err_method) { if (!err_method) {
write1(bell); // send out a bell character write1(ESC_BELL);
} else { } else {
flash(10); flash(10);
} }
@@ -2750,7 +2693,7 @@ static void show_status_line(void)
} }
have_status_msg = 0; have_status_msg = 0;
} }
place_cursor(crow, ccol, FALSE); // put cursor back in correct place place_cursor(crow, ccol); // put cursor back in correct place
} }
fflush_all(); fflush_all();
} }
@@ -2762,12 +2705,12 @@ static void status_line_bold(const char *format, ...)
va_list args; va_list args;
va_start(args, format); va_start(args, format);
strcpy(status_buffer, SOs); // Terminal standout mode on strcpy(status_buffer, ESC_BOLD_TEXT);
vsprintf(status_buffer + sizeof(SOs)-1, format, args); vsprintf(status_buffer + sizeof(ESC_BOLD_TEXT)-1, format, args);
strcat(status_buffer, SOn); // Terminal standout mode off strcat(status_buffer, ESC_NORM_TEXT);
va_end(args); va_end(args);
have_status_msg = 1 + sizeof(SOs) + sizeof(SOn) - 2; have_status_msg = 1 + sizeof(ESC_BOLD_TEXT) + sizeof(ESC_NORM_TEXT) - 2;
} }
// format status buffer // format status buffer
@@ -2799,8 +2742,8 @@ static void print_literal(char *buf, const char *s)
c = *s; c = *s;
c_is_no_print = (c & 0x80) && !Isprint(c); c_is_no_print = (c & 0x80) && !Isprint(c);
if (c_is_no_print) { if (c_is_no_print) {
strcpy(d, SOn); strcpy(d, ESC_NORM_TEXT);
d += sizeof(SOn)-1; d += sizeof(ESC_NORM_TEXT)-1;
c = '.'; c = '.';
} }
if (c < ' ' || c == 0x7f) { if (c < ' ' || c == 0x7f) {
@@ -2812,8 +2755,8 @@ static void print_literal(char *buf, const char *s)
*d++ = c; *d++ = c;
*d = '\0'; *d = '\0';
if (c_is_no_print) { if (c_is_no_print) {
strcpy(d, SOs); strcpy(d, ESC_BOLD_TEXT);
d += sizeof(SOs)-1; d += sizeof(ESC_BOLD_TEXT)-1;
} }
if (*s == '\n') { if (*s == '\n') {
*d++ = '$'; *d++ = '$';
@@ -2895,8 +2838,8 @@ static int format_edit_status(void)
//----- Force refresh of all Lines ----------------------------- //----- Force refresh of all Lines -----------------------------
static void redraw(int full_screen) static void redraw(int full_screen)
{ {
place_cursor(0, 0, FALSE); // put cursor in correct place place_cursor(0, 0);
clear_to_eos(); // tell terminal to erase display clear_to_eos();
screen_erase(); // erase the internal screen buffer screen_erase(); // erase the internal screen buffer
last_status_cksum = 0; // force status update last_status_cksum = 0; // force status update
refresh(full_screen); // this will redraw the entire display refresh(full_screen); // this will redraw the entire display
@@ -3036,22 +2979,13 @@ static void refresh(int full_screen)
if (changed) { if (changed) {
// copy changed part of buffer to virtual screen // copy changed part of buffer to virtual screen
memcpy(sp+cs, out_buf+cs, ce-cs+1); memcpy(sp+cs, out_buf+cs, ce-cs+1);
place_cursor(li, cs);
// move cursor to column of first change
//if (offset != old_offset) {
// // place_cursor is still too stupid
// // to handle offsets correctly
// place_cursor(li, cs, FALSE);
//} else {
place_cursor(li, cs, TRUE);
//}
// write line out to terminal // write line out to terminal
fwrite(&sp[cs], ce - cs + 1, 1, stdout); fwrite(&sp[cs], ce - cs + 1, 1, stdout);
} }
} }
place_cursor(crow, ccol, TRUE); place_cursor(crow, ccol);
old_offset = offset; old_offset = offset;
#undef old_offset #undef old_offset
@@ -3221,9 +3155,9 @@ static void do_cmd(int c)
break; break;
case 12: // ctrl-L force redraw whole screen case 12: // ctrl-L force redraw whole screen
case 18: // ctrl-R force redraw case 18: // ctrl-R force redraw
place_cursor(0, 0, FALSE); // put cursor in correct place place_cursor(0, 0);
clear_to_eos(); // tel terminal to erase display clear_to_eos();
mysleep(10); //mysleep(10); // why???
screen_erase(); // erase the internal screen buffer screen_erase(); // erase the internal screen buffer
last_status_cksum = 0; // force status update last_status_cksum = 0; // force status update
refresh(TRUE); // this will redraw the entire display refresh(TRUE); // this will redraw the entire display
@@ -4142,7 +4076,7 @@ static void crash_test()
if (msg[0]) { if (msg[0]) {
printf("\n\n%d: \'%c\' %s\n\n\n%s[Hit return to continue]%s", printf("\n\n%d: \'%c\' %s\n\n\n%s[Hit return to continue]%s",
totalcmds, last_input_char, msg, SOs, SOn); totalcmds, last_input_char, msg, ESC_BOLD_TEXT, ESC_NORM_TEXT);
fflush_all(); fflush_all();
while (safe_read(STDIN_FILENO, d, 1) > 0) { while (safe_read(STDIN_FILENO, d, 1) > 0) {
if (d[0] == '\n' || d[0] == '\r') if (d[0] == '\n' || d[0] == '\r')