diff options
Diffstat (limited to 'editors')
-rw-r--r-- | editors/vi.c | 188 |
1 files changed, 112 insertions, 76 deletions
diff --git a/editors/vi.c b/editors/vi.c index 374d161d1..ae86b7233 100644 --- a/editors/vi.c +++ b/editors/vi.c | |||
@@ -166,8 +166,9 @@ static int vi_setops; | |||
166 | 166 | ||
167 | 167 | ||
168 | static int editing; // >0 while we are editing a file | 168 | static int editing; // >0 while we are editing a file |
169 | static int cmd_mode; // 0=command 1=insert | 169 | static int cmd_mode; // 0=command 1=insert 2=replace |
170 | static int file_modified; // buffer contents changed | 170 | static int file_modified; // buffer contents changed |
171 | static int last_file_modified = -1; | ||
171 | static int fn_start; // index of first cmd line file name | 172 | static int fn_start; // index of first cmd line file name |
172 | static int save_argc; // how many file names on cmd line | 173 | static int save_argc; // how many file names on cmd line |
173 | static int cmdcnt; // repetition count | 174 | static int cmdcnt; // repetition count |
@@ -176,6 +177,9 @@ static struct timeval tv; // use select() for small sleeps | |||
176 | static int rows, columns; // the terminal screen is this size | 177 | static int rows, columns; // the terminal screen is this size |
177 | static int crow, ccol, offset; // cursor is on Crow x Ccol with Horz Ofset | 178 | static int crow, ccol, offset; // cursor is on Crow x Ccol with Horz Ofset |
178 | static Byte *status_buffer; // mesages to the user | 179 | static Byte *status_buffer; // mesages to the user |
180 | #define STATUS_BUFFER_LEN 200 | ||
181 | static int have_status_msg; // is default edit status needed? | ||
182 | static int last_status_cksum; // hash of current status line | ||
179 | static Byte *cfn; // previous, current, and next file name | 183 | static Byte *cfn; // previous, current, and next file name |
180 | static Byte *text, *end, *textend; // pointers to the user data in memory | 184 | static Byte *text, *end, *textend; // pointers to the user data in memory |
181 | static Byte *screen; // pointer to the virtual screen buffer | 185 | static Byte *screen; // pointer to the virtual screen buffer |
@@ -272,7 +276,7 @@ static void show_status_line(void); // put a message on the bottom line | |||
272 | static void psb(const char *, ...); // Print Status Buf | 276 | static void psb(const char *, ...); // Print Status Buf |
273 | static void psbs(const char *, ...); // Print Status Buf in standout mode | 277 | static void psbs(const char *, ...); // Print Status Buf in standout mode |
274 | static void ni(Byte *); // display messages | 278 | static void ni(Byte *); // display messages |
275 | static void edit_status(void); // show file status on status line | 279 | static int format_edit_status(void); // format file status on status line |
276 | static void redraw(int); // force a full screen refresh | 280 | static void redraw(int); // force a full screen refresh |
277 | static void format_line(Byte*, Byte*, int); | 281 | static void format_line(Byte*, Byte*, int); |
278 | static void refresh(int); // update the terminal from screen[] | 282 | static void refresh(int); // update the terminal from screen[] |
@@ -331,7 +335,7 @@ static void write1(const char *out) | |||
331 | extern int vi_main(int argc, char **argv) | 335 | extern int vi_main(int argc, char **argv) |
332 | { | 336 | { |
333 | int c; | 337 | int c; |
334 | RESERVE_CONFIG_BUFFER(STATUS_BUFFER, 200); | 338 | RESERVE_CONFIG_BUFFER(STATUS_BUFFER, STATUS_BUFFER_LEN); |
335 | 339 | ||
336 | #ifdef CONFIG_FEATURE_VI_YANKMARK | 340 | #ifdef CONFIG_FEATURE_VI_YANKMARK |
337 | int i; | 341 | int i; |
@@ -344,7 +348,7 @@ extern int vi_main(int argc, char **argv) | |||
344 | #endif /* CONFIG_FEATURE_VI_CRASHME */ | 348 | #endif /* CONFIG_FEATURE_VI_CRASHME */ |
345 | 349 | ||
346 | status_buffer = STATUS_BUFFER; | 350 | status_buffer = STATUS_BUFFER; |
347 | *status_buffer = '\0'; // clear status buffer | 351 | last_status_cksum = 0; |
348 | 352 | ||
349 | #ifdef CONFIG_FEATURE_VI_READONLY | 353 | #ifdef CONFIG_FEATURE_VI_READONLY |
350 | vi_readonly = readonly = FALSE; | 354 | vi_readonly = readonly = FALSE; |
@@ -450,7 +454,8 @@ static void edit_file(Byte * fn) | |||
450 | if (ch < 1) { | 454 | if (ch < 1) { |
451 | (void) char_insert(text, '\n'); // start empty buf with dummy line | 455 | (void) char_insert(text, '\n'); // start empty buf with dummy line |
452 | } | 456 | } |
453 | file_modified = FALSE; | 457 | file_modified = 0; |
458 | last_file_modified = -1; | ||
454 | #ifdef CONFIG_FEATURE_VI_YANKMARK | 459 | #ifdef CONFIG_FEATURE_VI_YANKMARK |
455 | YDreg = 26; // default Yank/Delete reg | 460 | YDreg = 26; // default Yank/Delete reg |
456 | Ureg = 27; // hold orig line for "U" cmd | 461 | Ureg = 27; // hold orig line for "U" cmd |
@@ -506,7 +511,6 @@ static void edit_file(Byte * fn) | |||
506 | adding2q = 0; | 511 | adding2q = 0; |
507 | #endif /* CONFIG_FEATURE_VI_DOT_CMD */ | 512 | #endif /* CONFIG_FEATURE_VI_DOT_CMD */ |
508 | redraw(FALSE); // dont force every col re-draw | 513 | redraw(FALSE); // dont force every col re-draw |
509 | edit_status(); | ||
510 | show_status_line(); | 514 | show_status_line(); |
511 | 515 | ||
512 | //------This is the main Vi cmd handling loop ----------------------- | 516 | //------This is the main Vi cmd handling loop ----------------------- |
@@ -834,7 +838,8 @@ static void colon(Byte * buf) | |||
834 | (void) char_insert(text, '\n'); | 838 | (void) char_insert(text, '\n'); |
835 | ch= 1; | 839 | ch= 1; |
836 | } | 840 | } |
837 | file_modified = FALSE; | 841 | file_modified = 0; |
842 | last_file_modified = -1; | ||
838 | #ifdef CONFIG_FEATURE_VI_YANKMARK | 843 | #ifdef CONFIG_FEATURE_VI_YANKMARK |
839 | if (Ureg >= 0 && Ureg < 28 && reg[Ureg] != 0) { | 844 | if (Ureg >= 0 && Ureg < 28 && reg[Ureg] != 0) { |
840 | free(reg[Ureg]); // free orig line reg- for 'U' | 845 | free(reg[Ureg]); // free orig line reg- for 'U' |
@@ -871,8 +876,7 @@ static void colon(Byte * buf) | |||
871 | cfn = (Byte *) bb_xstrdup((char *) args); | 876 | cfn = (Byte *) bb_xstrdup((char *) args); |
872 | } else { | 877 | } else { |
873 | // user wants file status info | 878 | // user wants file status info |
874 | edit_status(); | 879 | last_status_cksum = 0; // force status update |
875 | show_status_line(); | ||
876 | } | 880 | } |
877 | } else if (strncasecmp((char *) cmd, "features", i) == 0) { // what features are available | 881 | } else if (strncasecmp((char *) cmd, "features", i) == 0) { // what features are available |
878 | // print out values of all features | 882 | // print out values of all features |
@@ -978,7 +982,7 @@ static void colon(Byte * buf) | |||
978 | // if the insert is before "dot" then we need to update | 982 | // if the insert is before "dot" then we need to update |
979 | if (q <= dot) | 983 | if (q <= dot) |
980 | dot += ch; | 984 | dot += ch; |
981 | file_modified = TRUE; | 985 | file_modified++; |
982 | } | 986 | } |
983 | } else if (strncasecmp((char *) cmd, "rewind", i) == 0) { // rewind cmd line args | 987 | } else if (strncasecmp((char *) cmd, "rewind", i) == 0) { // rewind cmd line args |
984 | if (file_modified && ! useforce) { | 988 | if (file_modified && ! useforce) { |
@@ -1109,8 +1113,10 @@ static void colon(Byte * buf) | |||
1109 | forced = FALSE; | 1113 | forced = FALSE; |
1110 | } | 1114 | } |
1111 | psb("\"%s\" %dL, %dC", fn, li, l); | 1115 | psb("\"%s\" %dL, %dC", fn, li, l); |
1112 | if (q == text && r == end - 1 && l == ch) | 1116 | if (q == text && r == end - 1 && l == ch) { |
1113 | file_modified = FALSE; | 1117 | file_modified = 0; |
1118 | last_file_modified = -1; | ||
1119 | } | ||
1114 | if ((cmd[0] == 'x' || cmd[1] == 'q') && l == ch) { | 1120 | if ((cmd[0] == 'x' || cmd[1] == 'q') && l == ch) { |
1115 | editing = 0; | 1121 | editing = 0; |
1116 | } | 1122 | } |
@@ -1335,30 +1341,22 @@ static void dot_left(void) | |||
1335 | { | 1341 | { |
1336 | if (dot > text && dot[-1] != '\n') | 1342 | if (dot > text && dot[-1] != '\n') |
1337 | dot--; | 1343 | dot--; |
1338 | edit_status(); // show current file status | ||
1339 | show_status_line(); | ||
1340 | } | 1344 | } |
1341 | 1345 | ||
1342 | static void dot_right(void) | 1346 | static void dot_right(void) |
1343 | { | 1347 | { |
1344 | if (dot < end - 1 && *dot != '\n') | 1348 | if (dot < end - 1 && *dot != '\n') |
1345 | dot++; | 1349 | dot++; |
1346 | edit_status(); // show current file status | ||
1347 | show_status_line(); | ||
1348 | } | 1350 | } |
1349 | 1351 | ||
1350 | static void dot_begin(void) | 1352 | static void dot_begin(void) |
1351 | { | 1353 | { |
1352 | dot = begin_line(dot); // return pointer to first char cur line | 1354 | dot = begin_line(dot); // return pointer to first char cur line |
1353 | edit_status(); // show current file status | ||
1354 | show_status_line(); | ||
1355 | } | 1355 | } |
1356 | 1356 | ||
1357 | static void dot_end(void) | 1357 | static void dot_end(void) |
1358 | { | 1358 | { |
1359 | dot = end_line(dot); // return pointer to last char cur line | 1359 | dot = end_line(dot); // return pointer to last char cur line |
1360 | edit_status(); // show current file status | ||
1361 | show_status_line(); | ||
1362 | } | 1360 | } |
1363 | 1361 | ||
1364 | static Byte *move_to_col(Byte * p, int l) | 1362 | static Byte *move_to_col(Byte * p, int l) |
@@ -1383,15 +1381,11 @@ static Byte *move_to_col(Byte * p, int l) | |||
1383 | static void dot_next(void) | 1381 | static void dot_next(void) |
1384 | { | 1382 | { |
1385 | dot = next_line(dot); | 1383 | dot = next_line(dot); |
1386 | edit_status(); // show current file status | ||
1387 | show_status_line(); | ||
1388 | } | 1384 | } |
1389 | 1385 | ||
1390 | static void dot_prev(void) | 1386 | static void dot_prev(void) |
1391 | { | 1387 | { |
1392 | dot = prev_line(dot); | 1388 | dot = prev_line(dot); |
1393 | edit_status(); // show current file status | ||
1394 | show_status_line(); | ||
1395 | } | 1389 | } |
1396 | 1390 | ||
1397 | static void dot_scroll(int cnt, int dir) | 1391 | static void dot_scroll(int cnt, int dir) |
@@ -1416,8 +1410,6 @@ static void dot_scroll(int cnt, int dir) | |||
1416 | if (dot > q) | 1410 | if (dot > q) |
1417 | dot = begin_line(q); // is dot is below bottom line? | 1411 | dot = begin_line(q); // is dot is below bottom line? |
1418 | dot_skip_over_ws(); | 1412 | dot_skip_over_ws(); |
1419 | edit_status(); // show current file status | ||
1420 | show_status_line(); | ||
1421 | } | 1413 | } |
1422 | 1414 | ||
1423 | static void dot_skip_over_ws(void) | 1415 | static void dot_skip_over_ws(void) |
@@ -1603,12 +1595,12 @@ static Byte *char_insert(Byte * p, Byte c) // insert the char c at 'p' | |||
1603 | c = get_one_char(); | 1595 | c = get_one_char(); |
1604 | *p = c; | 1596 | *p = c; |
1605 | p++; | 1597 | p++; |
1606 | file_modified = TRUE; // has the file been modified | 1598 | file_modified++; // has the file been modified |
1607 | } else if (c == 27) { // Is this an ESC? | 1599 | } else if (c == 27) { // Is this an ESC? |
1608 | cmd_mode = 0; | 1600 | cmd_mode = 0; |
1609 | cmdcnt = 0; | 1601 | cmdcnt = 0; |
1610 | end_cmd_q(); // stop adding to q | 1602 | end_cmd_q(); // stop adding to q |
1611 | *status_buffer = '\0'; // clear the status buffer | 1603 | last_status_cksum = 0; // force status update |
1612 | if ((p[-1] != '\n') && (dot>text)) { | 1604 | if ((p[-1] != '\n') && (dot>text)) { |
1613 | p--; | 1605 | p--; |
1614 | } | 1606 | } |
@@ -1658,7 +1650,7 @@ static Byte *stupid_insert(Byte * p, Byte c) // stupidly insert the char c at 'p | |||
1658 | p = text_hole_make(p, 1); | 1650 | p = text_hole_make(p, 1); |
1659 | if (p != 0) { | 1651 | if (p != 0) { |
1660 | *p = c; | 1652 | *p = c; |
1661 | file_modified = TRUE; // has the file been modified | 1653 | file_modified++; // has the file been modified |
1662 | p++; | 1654 | p++; |
1663 | } | 1655 | } |
1664 | return (p); | 1656 | return (p); |
@@ -1856,7 +1848,7 @@ static Byte *text_hole_make(Byte * p, int size) // at "p", make a 'size' byte ho | |||
1856 | } | 1848 | } |
1857 | memset(p, ' ', size); // clear new hole | 1849 | memset(p, ' ', size); // clear new hole |
1858 | end = end + size; // adjust the new END | 1850 | end = end + size; // adjust the new END |
1859 | file_modified = TRUE; // has the file been modified | 1851 | file_modified++; // has the file been modified |
1860 | thm0: | 1852 | thm0: |
1861 | return (p); | 1853 | return (p); |
1862 | } | 1854 | } |
@@ -1892,7 +1884,7 @@ static Byte *text_hole_delete(Byte * p, Byte * q) // delete "p" thru "q", inclus | |||
1892 | dest = end - 1; // make sure dest in below end-1 | 1884 | dest = end - 1; // make sure dest in below end-1 |
1893 | if (end <= text) | 1885 | if (end <= text) |
1894 | dest = end = text; // keep pointers valid | 1886 | dest = end = text; // keep pointers valid |
1895 | file_modified = TRUE; // has the file been modified | 1887 | file_modified++; // has the file been modified |
1896 | thd0: | 1888 | thd0: |
1897 | return (dest); | 1889 | return (dest); |
1898 | } | 1890 | } |
@@ -2162,7 +2154,7 @@ static void winch_sig(int sig) | |||
2162 | static void cont_sig(int sig) | 2154 | static void cont_sig(int sig) |
2163 | { | 2155 | { |
2164 | rawmode(); // terminal to "raw" | 2156 | rawmode(); // terminal to "raw" |
2165 | *status_buffer = '\0'; // clear the status buffer | 2157 | last_status_cksum = 0; // force status update |
2166 | redraw(TRUE); // re-draw the screen | 2158 | redraw(TRUE); // re-draw the screen |
2167 | 2159 | ||
2168 | signal(SIGTSTP, suspend_sig); | 2160 | signal(SIGTSTP, suspend_sig); |
@@ -2407,7 +2399,7 @@ static Byte *get_input_line(Byte * prompt) // get input line- use "status line" | |||
2407 | static Byte *obufp = NULL; | 2399 | static Byte *obufp = NULL; |
2408 | 2400 | ||
2409 | strcpy((char *) buf, (char *) prompt); | 2401 | strcpy((char *) buf, (char *) prompt); |
2410 | *status_buffer = '\0'; // clear the status buffer | 2402 | last_status_cksum = 0; // force status update |
2411 | place_cursor(rows - 1, 0, FALSE); // go to Status line, bottom of screen | 2403 | place_cursor(rows - 1, 0, FALSE); // go to Status line, bottom of screen |
2412 | clear_to_eol(); // clear the line | 2404 | clear_to_eol(); // clear the line |
2413 | write1(prompt); // write out the :, /, or ? prompt | 2405 | write1(prompt); // write out the :, /, or ? prompt |
@@ -2512,7 +2504,7 @@ static int file_insert(Byte * fn, Byte * p, int size) | |||
2512 | psbs("could not read all of file \"%s\"", fn); | 2504 | psbs("could not read all of file \"%s\"", fn); |
2513 | } | 2505 | } |
2514 | if (cnt >= size) | 2506 | if (cnt >= size) |
2515 | file_modified = TRUE; | 2507 | file_modified++; |
2516 | fi0: | 2508 | fi0: |
2517 | return (cnt); | 2509 | return (cnt); |
2518 | } | 2510 | } |
@@ -2670,28 +2662,46 @@ static void screen_erase(void) | |||
2670 | memset(screen, ' ', screensize); // clear new screen | 2662 | memset(screen, ' ', screensize); // clear new screen |
2671 | } | 2663 | } |
2672 | 2664 | ||
2665 | static int bufsum(char *buf, int count) | ||
2666 | { | ||
2667 | int sum = 0; | ||
2668 | char *e = buf + count; | ||
2669 | while (buf < e) | ||
2670 | sum += *buf++; | ||
2671 | return sum; | ||
2672 | } | ||
2673 | |||
2673 | //----- Draw the status line at bottom of the screen ------------- | 2674 | //----- Draw the status line at bottom of the screen ------------- |
2674 | static void show_status_line(void) | 2675 | static void show_status_line(void) |
2675 | { | 2676 | { |
2676 | static int last_cksum; | 2677 | int cnt, cksum; |
2677 | int l, cnt, cksum; | ||
2678 | 2678 | ||
2679 | //edit_status(); | 2679 | // either we already have an error or status message, or we |
2680 | cnt = strlen((char *) status_buffer); | 2680 | // create one. |
2681 | for (cksum= l= 0; l < cnt; l++) { cksum += (int)(status_buffer[l]); } | 2681 | if (!have_status_msg) { |
2682 | // don't write the status line unless it changes | 2682 | cnt = format_edit_status(); |
2683 | if (cnt > 0 && last_cksum != cksum) { | 2683 | cksum = bufsum(status_buffer, cnt); |
2684 | last_cksum= cksum; // remember if we have seen this line | 2684 | } |
2685 | if (have_status_msg || ((cnt > 0 && last_status_cksum != cksum))) { | ||
2686 | last_status_cksum= cksum; // remember if we have seen this line | ||
2685 | place_cursor(rows - 1, 0, FALSE); // put cursor on status line | 2687 | place_cursor(rows - 1, 0, FALSE); // put cursor on status line |
2686 | write1(status_buffer); | 2688 | write1(status_buffer); |
2687 | clear_to_eol(); | 2689 | clear_to_eol(); |
2690 | if (have_status_msg) { | ||
2691 | if ((strlen(status_buffer) - (have_status_msg - 1)) > | ||
2692 | (columns - 1) ) { | ||
2693 | have_status_msg = 0; | ||
2694 | Hit_Return(); | ||
2695 | } | ||
2696 | have_status_msg = 0; | ||
2697 | } | ||
2688 | place_cursor(crow, ccol, FALSE); // put cursor back in correct place | 2698 | place_cursor(crow, ccol, FALSE); // put cursor back in correct place |
2689 | } | 2699 | } |
2690 | fflush(stdout); | 2700 | fflush(stdout); |
2691 | } | 2701 | } |
2692 | 2702 | ||
2693 | //----- format the status buffer, the bottom line of screen ------ | 2703 | //----- format the status buffer, the bottom line of screen ------ |
2694 | // print status buffer, with STANDOUT mode | 2704 | // format status buffer, with STANDOUT mode |
2695 | static void psbs(const char *format, ...) | 2705 | static void psbs(const char *format, ...) |
2696 | { | 2706 | { |
2697 | va_list args; | 2707 | va_list args; |
@@ -2701,12 +2711,13 @@ static void psbs(const char *format, ...) | |||
2701 | vsprintf((char *) status_buffer + strlen((char *) status_buffer), format, args); | 2711 | vsprintf((char *) status_buffer + strlen((char *) status_buffer), format, args); |
2702 | strcat((char *) status_buffer, SOn); // Terminal standout mode off | 2712 | strcat((char *) status_buffer, SOn); // Terminal standout mode off |
2703 | va_end(args); | 2713 | va_end(args); |
2704 | show_status_line(); | 2714 | |
2715 | have_status_msg = 1 + sizeof(SOs) + sizeof(SOn) - 2; | ||
2705 | 2716 | ||
2706 | return; | 2717 | return; |
2707 | } | 2718 | } |
2708 | 2719 | ||
2709 | // print status buffer | 2720 | // format status buffer |
2710 | static void psb(const char *format, ...) | 2721 | static void psb(const char *format, ...) |
2711 | { | 2722 | { |
2712 | va_list args; | 2723 | va_list args; |
@@ -2714,7 +2725,9 @@ static void psb(const char *format, ...) | |||
2714 | va_start(args, format); | 2725 | va_start(args, format); |
2715 | vsprintf((char *) status_buffer, format, args); | 2726 | vsprintf((char *) status_buffer, format, args); |
2716 | va_end(args); | 2727 | va_end(args); |
2717 | show_status_line(); | 2728 | |
2729 | have_status_msg = 1; | ||
2730 | |||
2718 | return; | 2731 | return; |
2719 | } | 2732 | } |
2720 | 2733 | ||
@@ -2726,12 +2739,28 @@ static void ni(Byte * s) // display messages | |||
2726 | psbs("\'%s\' is not implemented", buf); | 2739 | psbs("\'%s\' is not implemented", buf); |
2727 | } | 2740 | } |
2728 | 2741 | ||
2729 | static void edit_status(void) // show file status on status line | 2742 | static int format_edit_status(void) // show file status on status line |
2730 | { | 2743 | { |
2731 | int cur, tot, percent; | 2744 | int cur, percent, ret, trunc_at; |
2745 | static int tot; | ||
2732 | 2746 | ||
2747 | // file_modified is now a counter rather than a flag. this | ||
2748 | // helps reduce the amount of line counting we need to do. | ||
2749 | // (this will cause a mis-reporting of modified status | ||
2750 | // once every MAXINT editing operations.) | ||
2751 | |||
2752 | // it would be nice to do a similar optimization here -- if | ||
2753 | // we haven't done a motion that could have changed which line | ||
2754 | // we're on, then we shouldn't have to do this count_lines() | ||
2733 | cur = count_lines(text, dot); | 2755 | cur = count_lines(text, dot); |
2734 | tot = count_lines(text, end - 1); | 2756 | |
2757 | // reduce counting -- the total lines can't have | ||
2758 | // changed if we haven't done any edits. | ||
2759 | if (file_modified != last_file_modified) { | ||
2760 | tot = cur + count_lines(dot, end - 1) - 1; | ||
2761 | last_file_modified = file_modified; | ||
2762 | } | ||
2763 | |||
2735 | // current line percent | 2764 | // current line percent |
2736 | // ------------- ~~ ---------- | 2765 | // ------------- ~~ ---------- |
2737 | // total lines 100 | 2766 | // total lines 100 |
@@ -2742,18 +2771,27 @@ static void edit_status(void) // show file status on status line | |||
2742 | percent = 100; | 2771 | percent = 100; |
2743 | } | 2772 | } |
2744 | 2773 | ||
2745 | sprintf((char *) status_buffer, | 2774 | trunc_at = columns < STATUS_BUFFER_LEN-1 ? |
2746 | "\"%s\"" | 2775 | columns : STATUS_BUFFER_LEN-1; |
2776 | |||
2777 | ret = snprintf((char *) status_buffer, trunc_at+1, | ||
2747 | #ifdef CONFIG_FEATURE_VI_READONLY | 2778 | #ifdef CONFIG_FEATURE_VI_READONLY |
2748 | "%s" | 2779 | "%c %s%s%s %d/%d %d%%", |
2749 | #endif /* CONFIG_FEATURE_VI_READONLY */ | 2780 | #else |
2750 | "%s line %d of %d --%d%%--", | 2781 | "%c %s%s %d/%d %d%%", |
2751 | (cfn != 0 ? (char *) cfn : "No file"), | 2782 | #endif |
2783 | (cmd_mode ? (cmd_mode == 2 ? 'R':'I'):'-'), | ||
2784 | (cfn != 0 ? (char *) cfn : "No file"), | ||
2752 | #ifdef CONFIG_FEATURE_VI_READONLY | 2785 | #ifdef CONFIG_FEATURE_VI_READONLY |
2753 | ((vi_readonly || readonly) ? " [Read only]" : ""), | 2786 | ((vi_readonly || readonly) ? " [Read-only]" : ""), |
2754 | #endif /* CONFIG_FEATURE_VI_READONLY */ | 2787 | #endif |
2755 | (file_modified ? " [modified]" : ""), | 2788 | (file_modified ? " [modified]" : ""), |
2756 | cur, tot, percent); | 2789 | cur, tot, percent); |
2790 | |||
2791 | if (ret >= 0 && ret < trunc_at) | ||
2792 | return ret; /* it all fit */ | ||
2793 | |||
2794 | return trunc_at; /* had to truncate */ | ||
2757 | } | 2795 | } |
2758 | 2796 | ||
2759 | //----- Force refresh of all Lines ----------------------------- | 2797 | //----- Force refresh of all Lines ----------------------------- |
@@ -2762,7 +2800,9 @@ static void redraw(int full_screen) | |||
2762 | place_cursor(0, 0, FALSE); // put cursor in correct place | 2800 | place_cursor(0, 0, FALSE); // put cursor in correct place |
2763 | clear_to_eos(); // tel terminal to erase display | 2801 | clear_to_eos(); // tel terminal to erase display |
2764 | screen_erase(); // erase the internal screen buffer | 2802 | screen_erase(); // erase the internal screen buffer |
2803 | last_status_cksum = 0; // force status update | ||
2765 | refresh(full_screen); // this will redraw the entire display | 2804 | refresh(full_screen); // this will redraw the entire display |
2805 | show_status_line(); | ||
2766 | } | 2806 | } |
2767 | 2807 | ||
2768 | //----- Format a text[] line into a buffer --------------------- | 2808 | //----- Format a text[] line into a buffer --------------------- |
@@ -2899,8 +2939,6 @@ static void refresh(int full_screen) | |||
2899 | #endif /* CONFIG_FEATURE_VI_OPTIMIZE_CURSOR */ | 2939 | #endif /* CONFIG_FEATURE_VI_OPTIMIZE_CURSOR */ |
2900 | } | 2940 | } |
2901 | 2941 | ||
2902 | edit_status(); // show current file status | ||
2903 | show_status_line(); | ||
2904 | // write line out to terminal | 2942 | // write line out to terminal |
2905 | { | 2943 | { |
2906 | int nic = ce-cs+1; | 2944 | int nic = ce-cs+1; |
@@ -2960,6 +2998,8 @@ static void do_cmd(Byte c) | |||
2960 | p = q = save_dot = msg = buf; // quiet the compiler | 2998 | p = q = save_dot = msg = buf; // quiet the compiler |
2961 | memset(buf, '\0', 9); // clear buf | 2999 | memset(buf, '\0', 9); // clear buf |
2962 | 3000 | ||
3001 | show_status_line(); | ||
3002 | |||
2963 | /* if this is a cursor key, skip these checks */ | 3003 | /* if this is a cursor key, skip these checks */ |
2964 | switch (c) { | 3004 | switch (c) { |
2965 | case VI_K_UP: | 3005 | case VI_K_UP: |
@@ -3079,8 +3119,7 @@ key_cmd_mode: | |||
3079 | dot_scroll(rows - 2, 1); | 3119 | dot_scroll(rows - 2, 1); |
3080 | break; | 3120 | break; |
3081 | case 7: // ctrl-G show current status | 3121 | case 7: // ctrl-G show current status |
3082 | edit_status(); | 3122 | last_status_cksum = 0; // force status update |
3083 | show_status_line(); | ||
3084 | break; | 3123 | break; |
3085 | case 'h': // h- move left | 3124 | case 'h': // h- move left |
3086 | case VI_K_LEFT: // cursor key Left | 3125 | case VI_K_LEFT: // cursor key Left |
@@ -3090,8 +3129,6 @@ key_cmd_mode: | |||
3090 | do_cmd(c); | 3129 | do_cmd(c); |
3091 | } // repeat cnt | 3130 | } // repeat cnt |
3092 | dot_left(); | 3131 | dot_left(); |
3093 | edit_status(); // show current file status | ||
3094 | show_status_line(); | ||
3095 | break; | 3132 | break; |
3096 | case 10: // Newline ^J | 3133 | case 10: // Newline ^J |
3097 | case 'j': // j- goto next line, same col | 3134 | case 'j': // j- goto next line, same col |
@@ -3108,6 +3145,7 @@ key_cmd_mode: | |||
3108 | clear_to_eos(); // tel terminal to erase display | 3145 | clear_to_eos(); // tel terminal to erase display |
3109 | (void) mysleep(10); | 3146 | (void) mysleep(10); |
3110 | screen_erase(); // erase the internal screen buffer | 3147 | screen_erase(); // erase the internal screen buffer |
3148 | last_status_cksum = 0; // force status update | ||
3111 | refresh(TRUE); // this will redraw the entire display | 3149 | refresh(TRUE); // this will redraw the entire display |
3112 | break; | 3150 | break; |
3113 | case 13: // Carriage Return ^M | 3151 | case 13: // Carriage Return ^M |
@@ -3129,7 +3167,7 @@ key_cmd_mode: | |||
3129 | indicate_error(c); | 3167 | indicate_error(c); |
3130 | cmd_mode = 0; // stop insrting | 3168 | cmd_mode = 0; // stop insrting |
3131 | end_cmd_q(); | 3169 | end_cmd_q(); |
3132 | *status_buffer = '\0'; // clear status buffer | 3170 | last_status_cksum = 0; // force status update |
3133 | break; | 3171 | break; |
3134 | case ' ': // move right | 3172 | case ' ': // move right |
3135 | case 'l': // move right | 3173 | case 'l': // move right |
@@ -3349,7 +3387,7 @@ key_cmd_mode: | |||
3349 | msg = (Byte *) "Pattern not found"; | 3387 | msg = (Byte *) "Pattern not found"; |
3350 | } | 3388 | } |
3351 | dc2: | 3389 | dc2: |
3352 | psbs("%s", msg); | 3390 | if (*msg) psbs("%s", msg); |
3353 | break; | 3391 | break; |
3354 | case '{': // {- move backward paragraph | 3392 | case '{': // {- move backward paragraph |
3355 | q = char_search(dot, (Byte *) "\n\n", BACK, FULL); | 3393 | q = char_search(dot, (Byte *) "\n\n", BACK, FULL); |
@@ -3401,14 +3439,14 @@ key_cmd_mode: | |||
3401 | strncasecmp((char *) p, "wq", cnt) == 0 || | 3439 | strncasecmp((char *) p, "wq", cnt) == 0 || |
3402 | strncasecmp((char *) p, "x", cnt) == 0) { | 3440 | strncasecmp((char *) p, "x", cnt) == 0) { |
3403 | cnt = file_write(cfn, text, end - 1); | 3441 | cnt = file_write(cfn, text, end - 1); |
3404 | file_modified = FALSE; | 3442 | file_modified = 0; |
3443 | last_file_modified = -1; | ||
3405 | psb("\"%s\" %dL, %dC", cfn, count_lines(text, end - 1), cnt); | 3444 | psb("\"%s\" %dL, %dC", cfn, count_lines(text, end - 1), cnt); |
3406 | if (p[0] == 'x' || p[1] == 'q') { | 3445 | if (p[0] == 'x' || p[1] == 'q') { |
3407 | editing = 0; | 3446 | editing = 0; |
3408 | } | 3447 | } |
3409 | } else if (strncasecmp((char *) p, "file", cnt) == 0 ) { | 3448 | } else if (strncasecmp((char *) p, "file", cnt) == 0 ) { |
3410 | edit_status(); // show current file status | 3449 | last_status_cksum = 0; // force status update |
3411 | show_status_line(); | ||
3412 | } else if (sscanf((char *) p, "%d", &j) > 0) { | 3450 | } else if (sscanf((char *) p, "%d", &j) > 0) { |
3413 | dot = find_line(j); // go to line # j | 3451 | dot = find_line(j); // go to line # j |
3414 | dot_skip_over_ws(); | 3452 | dot_skip_over_ws(); |
@@ -3509,7 +3547,6 @@ key_cmd_mode: | |||
3509 | case VI_K_INSERT: // Cursor Key Insert | 3547 | case VI_K_INSERT: // Cursor Key Insert |
3510 | dc_i: | 3548 | dc_i: |
3511 | cmd_mode = 1; // start insrting | 3549 | cmd_mode = 1; // start insrting |
3512 | psb("-- Insert --"); | ||
3513 | break; | 3550 | break; |
3514 | case 'J': // J- join current and next lines together | 3551 | case 'J': // J- join current and next lines together |
3515 | if (cmdcnt-- > 2) { | 3552 | if (cmdcnt-- > 2) { |
@@ -3518,7 +3555,7 @@ key_cmd_mode: | |||
3518 | dot_end(); // move to NL | 3555 | dot_end(); // move to NL |
3519 | if (dot < end - 1) { // make sure not last char in text[] | 3556 | if (dot < end - 1) { // make sure not last char in text[] |
3520 | *dot++ = ' '; // replace NL with space | 3557 | *dot++ = ' '; // replace NL with space |
3521 | file_modified = TRUE; | 3558 | file_modified++; |
3522 | while (isblnk(*dot)) { // delete leading WS | 3559 | while (isblnk(*dot)) { // delete leading WS |
3523 | dot_delete(); | 3560 | dot_delete(); |
3524 | } | 3561 | } |
@@ -3559,7 +3596,6 @@ key_cmd_mode: | |||
3559 | case 'R': // R- continuous Replace char | 3596 | case 'R': // R- continuous Replace char |
3560 | dc5: | 3597 | dc5: |
3561 | cmd_mode = 2; | 3598 | cmd_mode = 2; |
3562 | psb("-- Replace --"); | ||
3563 | break; | 3599 | break; |
3564 | case 'X': // X- delete char before dot | 3600 | case 'X': // X- delete char before dot |
3565 | case 'x': // x- delete the current char | 3601 | case 'x': // x- delete the current char |
@@ -3709,7 +3745,7 @@ key_cmd_mode: | |||
3709 | c1 = get_one_char(); // get the replacement char | 3745 | c1 = get_one_char(); // get the replacement char |
3710 | if (*dot != '\n') { | 3746 | if (*dot != '\n') { |
3711 | *dot = c1; | 3747 | *dot = c1; |
3712 | file_modified = TRUE; // has the file been modified | 3748 | file_modified++; // has the file been modified |
3713 | } | 3749 | } |
3714 | end_cmd_q(); // stop adding to q | 3750 | end_cmd_q(); // stop adding to q |
3715 | break; | 3751 | break; |
@@ -3754,10 +3790,10 @@ key_cmd_mode: | |||
3754 | } // repeat cnt | 3790 | } // repeat cnt |
3755 | if (islower(*dot)) { | 3791 | if (islower(*dot)) { |
3756 | *dot = toupper(*dot); | 3792 | *dot = toupper(*dot); |
3757 | file_modified = TRUE; // has the file been modified | 3793 | file_modified++; // has the file been modified |
3758 | } else if (isupper(*dot)) { | 3794 | } else if (isupper(*dot)) { |
3759 | *dot = tolower(*dot); | 3795 | *dot = tolower(*dot); |
3760 | file_modified = TRUE; // has the file been modified | 3796 | file_modified++; // has the file been modified |
3761 | } | 3797 | } |
3762 | dot_right(); | 3798 | dot_right(); |
3763 | end_cmd_q(); // stop adding to q | 3799 | end_cmd_q(); // stop adding to q |