diff options
| author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-12-21 21:34:37 +0000 |
|---|---|---|
| committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-12-21 21:34:37 +0000 |
| commit | 26b6fba9d33bb4ce117db4ad22a94f05d04ff8be (patch) | |
| tree | 29d3d380a03219ec64c0f4720917d3fada20f2e5 | |
| parent | 619879246d57c9c54fa8e8eef138dde0876b0ef0 (diff) | |
| download | busybox-w32-26b6fba9d33bb4ce117db4ad22a94f05d04ff8be.tar.gz busybox-w32-26b6fba9d33bb4ce117db4ad22a94f05d04ff8be.tar.bz2 busybox-w32-26b6fba9d33bb4ce117db4ad22a94f05d04ff8be.zip | |
vi: fix a problem with displaying overlong lines
| -rw-r--r-- | editors/vi.c | 227 |
1 files changed, 120 insertions, 107 deletions
diff --git a/editors/vi.c b/editors/vi.c index 9426ab855..e58d6b310 100644 --- a/editors/vi.c +++ b/editors/vi.c | |||
| @@ -35,6 +35,7 @@ | |||
| 35 | enum { | 35 | enum { |
| 36 | MAX_LINELEN = CONFIG_FEATURE_VI_MAX_LEN, | 36 | MAX_LINELEN = CONFIG_FEATURE_VI_MAX_LEN, |
| 37 | MAX_SCR_COLS = CONFIG_FEATURE_VI_MAX_LEN, | 37 | MAX_SCR_COLS = CONFIG_FEATURE_VI_MAX_LEN, |
| 38 | MAX_TABSTOP = 32, // sanity limit | ||
| 38 | }; | 39 | }; |
| 39 | 40 | ||
| 40 | // Misc. non-Ascii keys that report an escape sequence | 41 | // Misc. non-Ascii keys that report an escape sequence |
| @@ -116,7 +117,8 @@ static int fn_start; // index of first cmd line file name | |||
| 116 | static int save_argc; // how many file names on cmd line | 117 | static int save_argc; // how many file names on cmd line |
| 117 | static int cmdcnt; // repetition count | 118 | static int cmdcnt; // repetition count |
| 118 | static int rows, columns; // the terminal screen is this size | 119 | static int rows, columns; // the terminal screen is this size |
| 119 | static int crow, ccol, offset; // cursor is on Crow x Ccol with Horz Ofset | 120 | static int crow, ccol; // cursor is on Crow x Ccol |
| 121 | static int offset; // chars scrolled off the screen to the left | ||
| 120 | static char *status_buffer; // mesages to the user | 122 | static char *status_buffer; // mesages to the user |
| 121 | #define STATUS_BUFFER_LEN 200 | 123 | #define STATUS_BUFFER_LEN 200 |
| 122 | static int have_status_msg; // is default edit status needed? | 124 | static int have_status_msg; // is default edit status needed? |
| @@ -253,6 +255,9 @@ static int file_insert(const char *, char *, int); | |||
| 253 | static int file_insert(const char *, char *); | 255 | static int file_insert(const char *, char *); |
| 254 | #endif | 256 | #endif |
| 255 | static int file_write(char *, char *, char *); | 257 | static int file_write(char *, char *, char *); |
| 258 | #if !ENABLE_FEATURE_VI_OPTIMIZE_CURSOR | ||
| 259 | #define place_cursor(a, b, optimize) place_cursor(a, b) | ||
| 260 | #endif | ||
| 256 | static void place_cursor(int, int, int); | 261 | static void place_cursor(int, int, int); |
| 257 | static void screen_erase(void); | 262 | static void screen_erase(void); |
| 258 | static void clear_to_eol(void); | 263 | static void clear_to_eol(void); |
| @@ -266,7 +271,7 @@ static void psbs(const char *, ...); // Print Status Buf in standout mode | |||
| 266 | static void ni(const char *); // display messages | 271 | static void ni(const char *); // display messages |
| 267 | static int format_edit_status(void); // format file status on status line | 272 | static int format_edit_status(void); // format file status on status line |
| 268 | static void redraw(int); // force a full screen refresh | 273 | static void redraw(int); // force a full screen refresh |
| 269 | static void format_line(char*, char*, int); | 274 | static int format_line(char*, char*, int); |
| 270 | static void refresh(int); // update the terminal from screen[] | 275 | static void refresh(int); // update the terminal from screen[] |
| 271 | 276 | ||
| 272 | static void Indicate_Error(void); // use flash or beep to indicate error | 277 | static void Indicate_Error(void); // use flash or beep to indicate error |
| @@ -992,7 +997,7 @@ static void colon(char * buf) | |||
| 992 | /* tabstopXXXX */ | 997 | /* tabstopXXXX */ |
| 993 | if (strncasecmp(argp + i, "tabstop=%d ", 7) == 0) { | 998 | if (strncasecmp(argp + i, "tabstop=%d ", 7) == 0) { |
| 994 | sscanf(strchr(argp + i, '='), "tabstop=%d" + 7, &ch); | 999 | sscanf(strchr(argp + i, '='), "tabstop=%d" + 7, &ch); |
| 995 | if (ch > 0 && ch < columns - 1) | 1000 | if (ch > 0 && ch <= MAX_TABSTOP) |
| 996 | tabstop = ch; | 1001 | tabstop = ch; |
| 997 | } | 1002 | } |
| 998 | while (*argp && *argp != ' ') | 1003 | while (*argp && *argp != ' ') |
| @@ -1252,7 +1257,7 @@ static char *end_line(char * p) // return pointer to NL of cur line line | |||
| 1252 | return p; | 1257 | return p; |
| 1253 | } | 1258 | } |
| 1254 | 1259 | ||
| 1255 | static inline char *dollar_line(char * p) // return pointer to just before NL line | 1260 | static char *dollar_line(char * p) // return pointer to just before NL line |
| 1256 | { | 1261 | { |
| 1257 | while (p < end - 1 && *p != '\n') | 1262 | while (p < end - 1 && *p != '\n') |
| 1258 | p++; // go to cur line E-o-l | 1263 | p++; // go to cur line E-o-l |
| @@ -1923,7 +1928,7 @@ static void show_help(void) | |||
| 1923 | ); | 1928 | ); |
| 1924 | } | 1929 | } |
| 1925 | 1930 | ||
| 1926 | static inline void print_literal(char * buf, const char * s) // copy s to buf, convert unprintable | 1931 | static void print_literal(char * buf, const char * s) // copy s to buf, convert unprintable |
| 1927 | { | 1932 | { |
| 1928 | unsigned char c; | 1933 | unsigned char c; |
| 1929 | char b[2]; | 1934 | char b[2]; |
| @@ -2055,7 +2060,7 @@ static void check_context(char cmd) | |||
| 2055 | } | 2060 | } |
| 2056 | } | 2061 | } |
| 2057 | 2062 | ||
| 2058 | static inline char *swap_context(char * p) // goto new context for '' command make this the current context | 2063 | static char *swap_context(char * p) // goto new context for '' command make this the current context |
| 2059 | { | 2064 | { |
| 2060 | char *tmp; | 2065 | char *tmp; |
| 2061 | 2066 | ||
| @@ -2147,7 +2152,7 @@ static int mysleep(int hund) // sleep for 'h' 1/100 seconds | |||
| 2147 | return safe_poll(pfd, 1, hund*10) > 0; | 2152 | return safe_poll(pfd, 1, hund*10) > 0; |
| 2148 | } | 2153 | } |
| 2149 | 2154 | ||
| 2150 | static int readed_for_parse; | 2155 | static int chars_to_parse; |
| 2151 | 2156 | ||
| 2152 | //----- IO Routines -------------------------------------------- | 2157 | //----- IO Routines -------------------------------------------- |
| 2153 | static char readit(void) // read (maybe cursor) key from stdin | 2158 | static char readit(void) // read (maybe cursor) key from stdin |
| @@ -2199,7 +2204,7 @@ static char readit(void) // read (maybe cursor) key from stdin | |||
| 2199 | 2204 | ||
| 2200 | alarm(0); // turn alarm OFF while we wait for input | 2205 | alarm(0); // turn alarm OFF while we wait for input |
| 2201 | fflush(stdout); | 2206 | fflush(stdout); |
| 2202 | n = readed_for_parse; | 2207 | n = chars_to_parse; |
| 2203 | // get input from User- are there already input chars in Q? | 2208 | // get input from User- are there already input chars in Q? |
| 2204 | if (n <= 0) { | 2209 | if (n <= 0) { |
| 2205 | // the Q is empty, wait for a typed char | 2210 | // the Q is empty, wait for a typed char |
| @@ -2228,7 +2233,7 @@ static char readit(void) // read (maybe cursor) key from stdin | |||
| 2228 | n += r; | 2233 | n += r; |
| 2229 | } | 2234 | } |
| 2230 | } | 2235 | } |
| 2231 | readed_for_parse = n; | 2236 | chars_to_parse = n; |
| 2232 | } | 2237 | } |
| 2233 | c = readbuffer[0]; | 2238 | c = readbuffer[0]; |
| 2234 | if (c == 27 && n > 1) { | 2239 | if (c == 27 && n > 1) { |
| @@ -2256,7 +2261,7 @@ static char readit(void) // read (maybe cursor) key from stdin | |||
| 2256 | n = 1; | 2261 | n = 1; |
| 2257 | } | 2262 | } |
| 2258 | // remove key sequence from Q | 2263 | // remove key sequence from Q |
| 2259 | readed_for_parse -= n; | 2264 | chars_to_parse -= n; |
| 2260 | memmove(readbuffer, readbuffer + n, MAX_LINELEN - n); | 2265 | memmove(readbuffer, readbuffer + n, MAX_LINELEN - n); |
| 2261 | alarm(3); // we are done waiting for input, turn alarm ON | 2266 | alarm(3); // we are done waiting for input, turn alarm ON |
| 2262 | return c; | 2267 | return c; |
| @@ -2265,7 +2270,7 @@ static char readit(void) // read (maybe cursor) key from stdin | |||
| 2265 | //----- IO Routines -------------------------------------------- | 2270 | //----- IO Routines -------------------------------------------- |
| 2266 | static char get_one_char(void) | 2271 | static char get_one_char(void) |
| 2267 | { | 2272 | { |
| 2268 | static char c; | 2273 | char c; |
| 2269 | 2274 | ||
| 2270 | #if ENABLE_FEATURE_VI_DOT_CMD | 2275 | #if ENABLE_FEATURE_VI_DOT_CMD |
| 2271 | // ! adding2q && ioq == 0 read() | 2276 | // ! adding2q && ioq == 0 read() |
| @@ -2290,7 +2295,7 @@ static char get_one_char(void) | |||
| 2290 | } else { | 2295 | } else { |
| 2291 | // adding STDIN chars to q | 2296 | // adding STDIN chars to q |
| 2292 | c = readit(); // get the users input | 2297 | c = readit(); // get the users input |
| 2293 | if (last_modifying_cmd != 0) { | 2298 | if (last_modifying_cmd != NULL) { |
| 2294 | int len = strlen(last_modifying_cmd); | 2299 | int len = strlen(last_modifying_cmd); |
| 2295 | if (len >= MAX_LINELEN - 1) { | 2300 | if (len >= MAX_LINELEN - 1) { |
| 2296 | psbs("last_modifying_cmd overrun"); | 2301 | psbs("last_modifying_cmd overrun"); |
| @@ -2303,17 +2308,18 @@ static char get_one_char(void) | |||
| 2303 | #else | 2308 | #else |
| 2304 | c = readit(); // get the users input | 2309 | c = readit(); // get the users input |
| 2305 | #endif /* FEATURE_VI_DOT_CMD */ | 2310 | #endif /* FEATURE_VI_DOT_CMD */ |
| 2306 | return c; // return the char, where ever it came from | 2311 | return c; |
| 2307 | } | 2312 | } |
| 2308 | 2313 | ||
| 2309 | static char *get_input_line(const char * prompt) // get input line- use "status line" | 2314 | static char *get_input_line(const char * prompt) // get input line- use "status line" |
| 2310 | { | 2315 | { |
| 2311 | static char *obufp; | 2316 | static char *buf; // [MAX_LINELEN] |
| 2312 | 2317 | ||
| 2313 | char buf[MAX_LINELEN]; | ||
| 2314 | char c; | 2318 | char c; |
| 2315 | int i; | 2319 | int i; |
| 2316 | 2320 | ||
| 2321 | if (!buf) buf = xmalloc(MAX_LINELEN); | ||
| 2322 | |||
| 2317 | strcpy(buf, prompt); | 2323 | strcpy(buf, prompt); |
| 2318 | last_status_cksum = 0; // force status update | 2324 | last_status_cksum = 0; // force status update |
| 2319 | place_cursor(rows - 1, 0, FALSE); // go to Status line, bottom of screen | 2325 | place_cursor(rows - 1, 0, FALSE); // go to Status line, bottom of screen |
| @@ -2329,7 +2335,7 @@ static char *get_input_line(const char * prompt) // get input line- use "status | |||
| 2329 | // user wants to erase prev char | 2335 | // user wants to erase prev char |
| 2330 | i--; // backup to prev char | 2336 | i--; // backup to prev char |
| 2331 | buf[i] = '\0'; // erase the char | 2337 | buf[i] = '\0'; // erase the char |
| 2332 | buf[i + 1] = '\0'; // null terminate buffer | 2338 | //buf[i + 1] = '\0'; // null terminate buffer |
| 2333 | write1("\b \b"); // erase char on screen | 2339 | write1("\b \b"); // erase char on screen |
| 2334 | if (i <= 0) { // user backs up before b-o-l, exit | 2340 | if (i <= 0) { // user backs up before b-o-l, exit |
| 2335 | break; | 2341 | break; |
| @@ -2342,9 +2348,7 @@ static char *get_input_line(const char * prompt) // get input line- use "status | |||
| 2342 | } | 2348 | } |
| 2343 | } | 2349 | } |
| 2344 | refresh(FALSE); | 2350 | refresh(FALSE); |
| 2345 | free(obufp); | 2351 | return buf; |
| 2346 | obufp = xstrdup(buf); | ||
| 2347 | return obufp; | ||
| 2348 | } | 2352 | } |
| 2349 | 2353 | ||
| 2350 | static int file_size(const char *fn) // what is the byte size of "fn" | 2354 | static int file_size(const char *fn) // what is the byte size of "fn" |
| @@ -2434,12 +2438,11 @@ static int file_write(char * fn, char * first, char * last) | |||
| 2434 | return -2; | 2438 | return -2; |
| 2435 | } | 2439 | } |
| 2436 | charcnt = 0; | 2440 | charcnt = 0; |
| 2437 | // FIXIT- use the correct umask() | 2441 | fd = open(fn, (O_WRONLY | O_CREAT | O_TRUNC), 0666); |
| 2438 | fd = open(fn, (O_WRONLY | O_CREAT | O_TRUNC), 0664); | ||
| 2439 | if (fd < 0) | 2442 | if (fd < 0) |
| 2440 | return -1; | 2443 | return -1; |
| 2441 | cnt = last - first + 1; | 2444 | cnt = last - first + 1; |
| 2442 | charcnt = write(fd, first, cnt); | 2445 | charcnt = full_write(fd, first, cnt); |
| 2443 | if (charcnt == cnt) { | 2446 | if (charcnt == cnt) { |
| 2444 | // good write | 2447 | // good write |
| 2445 | //file_modified = FALSE; // the file has not been modified | 2448 | //file_modified = FALSE; // the file has not been modified |
| @@ -2459,22 +2462,13 @@ static int file_write(char * fn, char * first, char * last) | |||
| 2459 | // . ... . | 2462 | // . ... . |
| 2460 | // . ... . | 2463 | // . ... . |
| 2461 | // 22,0 ... 22,79 | 2464 | // 22,0 ... 22,79 |
| 2462 | // 23,0 ... 23,79 status line | 2465 | // 23,0 ... 23,79 <- status line |
| 2463 | // | ||
| 2464 | 2466 | ||
| 2465 | //----- Move the cursor to row x col (count from 0, not 1) ------- | 2467 | //----- Move the cursor to row x col (count from 0, not 1) ------- |
| 2466 | static void place_cursor(int row, int col, int opti) | 2468 | static void place_cursor(int row, int col, int optimize) |
| 2467 | { | 2469 | { |
| 2468 | char cm1[MAX_LINELEN]; | 2470 | char cm1[32]; |
| 2469 | char *cm; | 2471 | char *cm; |
| 2470 | #if ENABLE_FEATURE_VI_OPTIMIZE_CURSOR | ||
| 2471 | char cm2[MAX_LINELEN]; | ||
| 2472 | char *screenp; | ||
| 2473 | // char cm3[MAX_LINELEN]; | ||
| 2474 | int Rrow = last_row; | ||
| 2475 | #endif | ||
| 2476 | |||
| 2477 | memset(cm1, '\0', MAX_LINELEN); // clear the buffer | ||
| 2478 | 2472 | ||
| 2479 | if (row < 0) row = 0; | 2473 | if (row < 0) row = 0; |
| 2480 | if (row >= rows) row = rows - 1; | 2474 | if (row >= rows) row = rows - 1; |
| @@ -2484,45 +2478,42 @@ static void place_cursor(int row, int col, int opti) | |||
| 2484 | //----- 1. Try the standard terminal ESC sequence | 2478 | //----- 1. Try the standard terminal ESC sequence |
| 2485 | sprintf(cm1, CMrc, row + 1, col + 1); | 2479 | sprintf(cm1, CMrc, row + 1, col + 1); |
| 2486 | cm = cm1; | 2480 | cm = cm1; |
| 2487 | if (!opti) | ||
| 2488 | goto pc0; | ||
| 2489 | 2481 | ||
| 2490 | #if ENABLE_FEATURE_VI_OPTIMIZE_CURSOR | 2482 | #if ENABLE_FEATURE_VI_OPTIMIZE_CURSOR |
| 2491 | //----- find the minimum # of chars to move cursor ------------- | 2483 | if (optimize && col < 16) { |
| 2492 | //----- 2. Try moving with discreet chars (Newline, [back]space, ...) | 2484 | char cm2[MAX_LINELEN]; // better size estimate? |
| 2493 | memset(cm2, '\0', MAX_LINELEN); // clear the buffer | 2485 | char *screenp; |
| 2486 | int Rrow = last_row; | ||
| 2494 | 2487 | ||
| 2495 | // move to the correct row | 2488 | //----- find the minimum # of chars to move cursor ------------- |
| 2496 | while (row < Rrow) { | 2489 | //----- 2. Try moving with discreet chars (Newline, [back]space, ...) |
| 2497 | // the cursor has to move up | 2490 | cm2[0] = '\0'; |
| 2498 | strcat(cm2, CMup); | ||
| 2499 | Rrow--; | ||
| 2500 | } | ||
| 2501 | while (row > Rrow) { | ||
| 2502 | // the cursor has to move down | ||
| 2503 | strcat(cm2, CMdown); | ||
| 2504 | Rrow++; | ||
| 2505 | } | ||
| 2506 | 2491 | ||
| 2507 | // now move to the correct column | 2492 | // move to the correct row |
| 2508 | strcat(cm2, "\r"); // start at col 0 | 2493 | while (row < Rrow) { |
| 2509 | // just send out orignal source char to get to correct place | 2494 | // the cursor has to move up |
| 2510 | screenp = &screen[row * columns]; // start of screen line | 2495 | strcat(cm2, CMup); |
| 2511 | strncat(cm2, screenp, col); | 2496 | Rrow--; |
| 2497 | } | ||
| 2498 | while (row > Rrow) { | ||
| 2499 | // the cursor has to move down | ||
| 2500 | strcat(cm2, CMdown); | ||
| 2501 | Rrow++; | ||
| 2502 | } | ||
| 2512 | 2503 | ||
| 2513 | //----- 3. Try some other way of moving cursor | 2504 | // now move to the correct column |
| 2514 | //--------------------------------------------- | 2505 | strcat(cm2, "\r"); // start at col 0 |
| 2506 | // just send out orignal source char to get to correct place | ||
| 2507 | screenp = &screen[row * columns]; // start of screen line | ||
| 2508 | strncat(cm2, screenp, col); | ||
| 2515 | 2509 | ||
| 2516 | // pick the shortest cursor motion to send out | 2510 | // pick the shortest cursor motion to send out |
| 2517 | cm = cm1; | 2511 | if (strlen(cm2) < strlen(cm)) { |
| 2518 | if (strlen(cm2) < strlen(cm)) { | 2512 | cm = cm2; |
| 2519 | cm = cm2; | 2513 | } |
| 2520 | } /* else if (strlen(cm3) < strlen(cm)) { | 2514 | } |
| 2521 | cm= cm3; | ||
| 2522 | } */ | ||
| 2523 | #endif /* FEATURE_VI_OPTIMIZE_CURSOR */ | 2515 | #endif /* FEATURE_VI_OPTIMIZE_CURSOR */ |
| 2524 | pc0: | 2516 | write1(cm); |
| 2525 | write1(cm); // move the cursor | ||
| 2526 | } | 2517 | } |
| 2527 | 2518 | ||
| 2528 | //----- Erase from cursor to end of line ----------------------- | 2519 | //----- Erase from cursor to end of line ----------------------- |
| @@ -2721,11 +2712,15 @@ static void redraw(int full_screen) | |||
| 2721 | } | 2712 | } |
| 2722 | 2713 | ||
| 2723 | //----- Format a text[] line into a buffer --------------------- | 2714 | //----- Format a text[] line into a buffer --------------------- |
| 2724 | static void format_line(char *dest, char *src, int li) | 2715 | // Returns number of leading chars which should be ignored |
| 2716 | // (return value is always <= offset) | ||
| 2717 | static int format_line(char *dest, char *src, int li) | ||
| 2725 | { | 2718 | { |
| 2726 | int co; | ||
| 2727 | char c; | 2719 | char c; |
| 2720 | int co; | ||
| 2721 | int ofs = offset; | ||
| 2728 | 2722 | ||
| 2723 | memset(dest, ' ', MAX_SCR_COLS); | ||
| 2729 | for (co = 0; co < MAX_SCR_COLS; co++) { | 2724 | for (co = 0; co < MAX_SCR_COLS; co++) { |
| 2730 | c = ' '; // assume blank | 2725 | c = ' '; // assume blank |
| 2731 | if (li > 0 && co == 0) { | 2726 | if (li > 0 && co == 0) { |
| @@ -2734,33 +2729,52 @@ static void format_line(char *dest, char *src, int li) | |||
| 2734 | // are there chars in text[] and have we gone past the end | 2729 | // are there chars in text[] and have we gone past the end |
| 2735 | if (text < end && src < end) { | 2730 | if (text < end && src < end) { |
| 2736 | c = *src++; | 2731 | c = *src++; |
| 2737 | } | 2732 | |
| 2738 | if (c == '\n') | 2733 | if (c == '\n') |
| 2739 | break; | 2734 | break; |
| 2740 | if ((c & 0x80) && !Isprint(c)) { | 2735 | if ((c & 0x80) && !Isprint(c)) { |
| 2741 | c = '.'; | 2736 | c = '.'; |
| 2742 | } | 2737 | } |
| 2743 | if ((unsigned char)(c) < ' ' || c == 0x7f) { | 2738 | if ((unsigned char)(c) < ' ' || c == 0x7f) { |
| 2744 | if (c == '\t') { | 2739 | if (c == '\t') { |
| 2745 | c = ' '; | 2740 | c = ' '; |
| 2746 | // co % 8 != 7 | 2741 | // co % 8 != 7 |
| 2747 | for (; (co % tabstop) != (tabstop - 1); co++) { | 2742 | while ((co % tabstop) != (tabstop - 1)) { |
| 2748 | dest[co] = c; | 2743 | dest[co++] = c; |
| 2744 | if (co >= MAX_SCR_COLS) | ||
| 2745 | goto ret; | ||
| 2746 | } | ||
| 2747 | } else { | ||
| 2748 | dest[co++] = '^'; | ||
| 2749 | if (co >= MAX_SCR_COLS) | ||
| 2750 | goto ret; | ||
| 2751 | if (c == 0x7f) | ||
| 2752 | c = '?'; | ||
| 2753 | else | ||
| 2754 | c += '@'; // make it visible | ||
| 2749 | } | 2755 | } |
| 2750 | } else { | ||
| 2751 | dest[co++] = '^'; | ||
| 2752 | if (c == 0x7f) | ||
| 2753 | c = '?'; | ||
| 2754 | else | ||
| 2755 | c += '@'; // make it visible | ||
| 2756 | } | 2756 | } |
| 2757 | } | 2757 | } |
| 2758 | // the co++ is done here so that the column will | 2758 | // the co++ is done here so that the column will |
| 2759 | // not be overwritten when we blank-out the rest of line | 2759 | // not be overwritten when we blank-out the rest of line |
| 2760 | dest[co] = c; | 2760 | dest[co] = c; |
| 2761 | // discard scrolled-off portion, in tabstop-sized pieces | ||
| 2762 | if (ofs >= tabstop && co >= tabstop) { | ||
| 2763 | co -= tabstop; | ||
| 2764 | ofs -= tabstop; | ||
| 2765 | memset(&dest[co + 1], ' ', tabstop); | ||
| 2766 | } | ||
| 2761 | if (src >= end) | 2767 | if (src >= end) |
| 2762 | break; | 2768 | break; |
| 2763 | } | 2769 | } |
| 2770 | ret: | ||
| 2771 | if (co < ofs) { | ||
| 2772 | // entire line has scrolled off, make it entirely blank | ||
| 2773 | memset(dest, ' ', MAX_SCR_COLS); | ||
| 2774 | ofs = 0; | ||
| 2775 | } | ||
| 2776 | dest[MAX_SCR_COLS-1] = '\0'; | ||
| 2777 | return ofs; | ||
| 2764 | } | 2778 | } |
| 2765 | 2779 | ||
| 2766 | //----- Refresh the changed screen lines ----------------------- | 2780 | //----- Refresh the changed screen lines ----------------------- |
| @@ -2786,19 +2800,19 @@ static void refresh(int full_screen) | |||
| 2786 | 2800 | ||
| 2787 | // compare text[] to screen[] and mark screen[] lines that need updating | 2801 | // compare text[] to screen[] and mark screen[] lines that need updating |
| 2788 | for (li = 0; li < rows - 1; li++) { | 2802 | for (li = 0; li < rows - 1; li++) { |
| 2803 | int ofs; | ||
| 2789 | int cs, ce; // column start & end | 2804 | int cs, ce; // column start & end |
| 2790 | memset(buf, ' ', MAX_SCR_COLS); // blank-out the buffer | ||
| 2791 | buf[MAX_SCR_COLS-1] = 0; // NULL terminate the buffer | ||
| 2792 | // format current text line into buf | 2805 | // format current text line into buf |
| 2793 | format_line(buf, tp, li); | 2806 | ofs = format_line(buf, tp, li); |
| 2794 | 2807 | ||
| 2795 | // skip to the end of the current text[] line | 2808 | // skip to the end of the current text[] line |
| 2796 | while (tp < end && *tp++ != '\n') /*no-op*/; | 2809 | while (tp < end && *tp++ != '\n') |
| 2810 | continue; | ||
| 2797 | 2811 | ||
| 2798 | // see if there are any changes between vitual screen and buf | 2812 | // see if there are any changes between vitual screen and buf |
| 2799 | changed = FALSE; // assume no change | 2813 | changed = FALSE; // assume no change |
| 2800 | cs= 0; | 2814 | cs = 0; |
| 2801 | ce= columns-1; | 2815 | ce = columns - 1; |
| 2802 | sp = &screen[li * columns]; // start of screen line | 2816 | sp = &screen[li * columns]; // start of screen line |
| 2803 | if (full_screen) { | 2817 | if (full_screen) { |
| 2804 | // force re-draw of every single column from 0 - columns-1 | 2818 | // force re-draw of every single column from 0 - columns-1 |
| @@ -2807,15 +2821,15 @@ static void refresh(int full_screen) | |||
| 2807 | // compare newly formatted buffer with virtual screen | 2821 | // compare newly formatted buffer with virtual screen |
| 2808 | // look forward for first difference between buf and screen | 2822 | // look forward for first difference between buf and screen |
| 2809 | for (; cs <= ce; cs++) { | 2823 | for (; cs <= ce; cs++) { |
| 2810 | if (buf[cs + offset] != sp[cs]) { | 2824 | if (buf[cs + ofs] != sp[cs]) { |
| 2811 | changed = TRUE; // mark for redraw | 2825 | changed = TRUE; // mark for redraw |
| 2812 | break; | 2826 | break; |
| 2813 | } | 2827 | } |
| 2814 | } | 2828 | } |
| 2815 | 2829 | ||
| 2816 | // look backward for last difference between buf and screen | 2830 | // look backward for last difference between buf and screen |
| 2817 | for ( ; ce >= cs; ce--) { | 2831 | for (; ce >= cs; ce--) { |
| 2818 | if (buf[ce + offset] != sp[ce]) { | 2832 | if (buf[ce + ofs] != sp[ce]) { |
| 2819 | changed = TRUE; // mark for redraw | 2833 | changed = TRUE; // mark for redraw |
| 2820 | break; | 2834 | break; |
| 2821 | } | 2835 | } |
| @@ -2829,13 +2843,13 @@ static void refresh(int full_screen) | |||
| 2829 | } | 2843 | } |
| 2830 | 2844 | ||
| 2831 | // make a sanity check of columns indexes | 2845 | // make a sanity check of columns indexes |
| 2832 | if (cs < 0) cs= 0; | 2846 | if (cs < 0) cs = 0; |
| 2833 | if (ce > columns-1) ce= columns-1; | 2847 | if (ce > columns - 1) ce = columns - 1; |
| 2834 | if (cs > ce) { cs= 0; ce= columns-1; } | 2848 | if (cs > ce) { cs = 0; ce = columns - 1; } |
| 2835 | // is there a change between vitual screen and buf | 2849 | // is there a change between vitual screen and buf |
| 2836 | if (changed) { | 2850 | if (changed) { |
| 2837 | // copy changed part of buffer to virtual screen | 2851 | // copy changed part of buffer to virtual screen |
| 2838 | memmove(sp+cs, buf+(cs+offset), ce-cs+1); | 2852 | memmove(sp+cs, buf+(cs+ofs), ce-cs+1); |
| 2839 | 2853 | ||
| 2840 | // move cursor to column of first change | 2854 | // move cursor to column of first change |
| 2841 | if (offset != old_offset) { | 2855 | if (offset != old_offset) { |
| @@ -2848,7 +2862,7 @@ static void refresh(int full_screen) | |||
| 2848 | // try to optimize cursor movement | 2862 | // try to optimize cursor movement |
| 2849 | // otherwise, use standard ESC sequence | 2863 | // otherwise, use standard ESC sequence |
| 2850 | place_cursor(li, cs, li == (last_li+1) ? TRUE : FALSE); | 2864 | place_cursor(li, cs, li == (last_li+1) ? TRUE : FALSE); |
| 2851 | last_li= li; | 2865 | last_li = li; |
| 2852 | #else | 2866 | #else |
| 2853 | place_cursor(li, cs, FALSE); // use standard ESC sequence | 2867 | place_cursor(li, cs, FALSE); // use standard ESC sequence |
| 2854 | #endif /* FEATURE_VI_OPTIMIZE_CURSOR */ | 2868 | #endif /* FEATURE_VI_OPTIMIZE_CURSOR */ |
| @@ -2859,7 +2873,7 @@ static void refresh(int full_screen) | |||
| 2859 | int nic = ce - cs + 1; | 2873 | int nic = ce - cs + 1; |
| 2860 | char *out = sp + cs; | 2874 | char *out = sp + cs; |
| 2861 | 2875 | ||
| 2862 | while (nic-- > 0) { | 2876 | while (--nic >= 0) { |
| 2863 | bb_putchar(*out); | 2877 | bb_putchar(*out); |
| 2864 | out++; | 2878 | out++; |
| 2865 | } | 2879 | } |
| @@ -2877,8 +2891,7 @@ static void refresh(int full_screen) | |||
| 2877 | place_cursor(crow, ccol, FALSE); | 2891 | place_cursor(crow, ccol, FALSE); |
| 2878 | #endif | 2892 | #endif |
| 2879 | 2893 | ||
| 2880 | if (offset != old_offset) | 2894 | old_offset = offset; |
| 2881 | old_offset = offset; | ||
| 2882 | } | 2895 | } |
| 2883 | 2896 | ||
| 2884 | //--------------------------------------------------------------------- | 2897 | //--------------------------------------------------------------------- |
| @@ -3230,7 +3243,7 @@ static void do_cmd(char c) | |||
| 3230 | case '.': // .- repeat the last modifying command | 3243 | case '.': // .- repeat the last modifying command |
| 3231 | // Stuff the last_modifying_cmd back into stdin | 3244 | // Stuff the last_modifying_cmd back into stdin |
| 3232 | // and let it be re-executed. | 3245 | // and let it be re-executed. |
| 3233 | if (last_modifying_cmd != 0) { | 3246 | if (last_modifying_cmd != NULL) { |
| 3234 | ioq = ioq_start = xstrdup(last_modifying_cmd); | 3247 | ioq = ioq_start = xstrdup(last_modifying_cmd); |
| 3235 | } | 3248 | } |
| 3236 | break; | 3249 | break; |
| @@ -3844,7 +3857,7 @@ static void crash_dummy() | |||
| 3844 | cmd1 = " \n\r\002\004\005\006\025\0310^$-+wWeEbBhjklHL"; | 3857 | cmd1 = " \n\r\002\004\005\006\025\0310^$-+wWeEbBhjklHL"; |
| 3845 | 3858 | ||
| 3846 | // is there already a command running? | 3859 | // is there already a command running? |
| 3847 | if (readed_for_parse > 0) | 3860 | if (chars_to_parse > 0) |
| 3848 | goto cd1; | 3861 | goto cd1; |
| 3849 | cd0: | 3862 | cd0: |
| 3850 | startrbi = rbi = 0; | 3863 | startrbi = rbi = 0; |
| @@ -3921,7 +3934,7 @@ static void crash_dummy() | |||
| 3921 | } | 3934 | } |
| 3922 | strcat(readbuffer, "\033"); | 3935 | strcat(readbuffer, "\033"); |
| 3923 | } | 3936 | } |
| 3924 | readed_for_parse = strlen(readbuffer); | 3937 | chars_to_parse = strlen(readbuffer); |
| 3925 | cd1: | 3938 | cd1: |
| 3926 | totalcmds++; | 3939 | totalcmds++; |
| 3927 | if (sleeptime > 0) | 3940 | if (sleeptime > 0) |
