aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2021-04-06 13:39:48 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2021-04-11 00:18:55 +0200
commit7ce0e75c1f26d9cb3061c64aeab3204f62a5b55c (patch)
tree403b55810b02141f10a15da7fd063be53870b71e
parent9f017d9db0eb5522eb9c140a2d839461c677eb8e (diff)
downloadbusybox-w32-7ce0e75c1f26d9cb3061c64aeab3204f62a5b55c.tar.gz
busybox-w32-7ce0e75c1f26d9cb3061c64aeab3204f62a5b55c.tar.bz2
busybox-w32-7ce0e75c1f26d9cb3061c64aeab3204f62a5b55c.zip
vi: code shrink search commands
Changes to search commands ('/', '?', 'n' and 'N'): - Rewrite to be smaller and (possibly) clearer. - Issue a warning when a repeat search is requested without a previous search having been made. Vim and BusyBox vi support a repetition count for searches though the original vi doesn't. If the count exceeds the number of occurrences of the search string the search may loop through the file multiple times. function old new delta .rodata 105135 105119 -16 do_cmd 4898 4860 -38 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-54) Total: -54 bytes Signed-off-by; Ron Yorston <rmy@pobox.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--editors/vi.c85
1 files changed, 36 insertions, 49 deletions
diff --git a/editors/vi.c b/editors/vi.c
index 1c5a32bf9..5dc14f1ba 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -3486,70 +3486,57 @@ static void do_cmd(int c)
3486 break; 3486 break;
3487#endif 3487#endif
3488#if ENABLE_FEATURE_VI_SEARCH 3488#if ENABLE_FEATURE_VI_SEARCH
3489 case '?': // /- search for a pattern 3489 case 'N': // N- backward search for last pattern
3490 case '/': // /- search for a pattern 3490 dir = last_search_pattern[0] == '/' ? BACK : FORWARD;
3491 goto dc4; // now search for pattern
3492 break;
3493 case '?': // ?- backward search for a pattern
3494 case '/': // /- forward search for a pattern
3491 buf[0] = c; 3495 buf[0] = c;
3492 buf[1] = '\0'; 3496 buf[1] = '\0';
3493 q = get_input_line(buf); // get input line- use "status line" 3497 q = get_input_line(buf); // get input line- use "status line"
3494 if (q[0] && !q[1]) { 3498 if (!q[0]) // user changed mind and erased the "/"- do nothing
3499 break;
3500 if (!q[1]) { // if no pat re-use old pat
3495 if (last_search_pattern[0]) 3501 if (last_search_pattern[0])
3496 last_search_pattern[0] = c; 3502 last_search_pattern[0] = c;
3497 goto dc3; // if no pat re-use old pat 3503 } else { // strlen(q) > 1: new pat- save it and find
3498 }
3499 if (q[0]) { // strlen(q) > 1: new pat- save it and find
3500 // there is a new pat
3501 free(last_search_pattern); 3504 free(last_search_pattern);
3502 last_search_pattern = xstrdup(q); 3505 last_search_pattern = xstrdup(q);
3503 goto dc3; // now find the pattern
3504 } 3506 }
3505 // user changed mind and erased the "/"- do nothing 3507 // fall through
3506 break;
3507 case 'N': // N- backward search for last pattern
3508 dir = BACK; // assume BACKWARD search
3509 p = dot - 1;
3510 if (last_search_pattern[0] == '?') {
3511 dir = FORWARD;
3512 p = dot + 1;
3513 }
3514 goto dc4; // now search for pattern
3515 break;
3516 case 'n': // n- repeat search for last pattern 3508 case 'n': // n- repeat search for last pattern
3517 // search rest of text[] starting at next char 3509 // search rest of text[] starting at next char
3518 // if search fails return orignal "p" not the "p+1" address 3510 // if search fails "dot" is unchanged
3519 do { 3511 dir = last_search_pattern[0] == '/' ? FORWARD : BACK;
3520 const char *msg;
3521 dc3:
3522 dir = FORWARD; // assume FORWARD search
3523 p = dot + 1;
3524 if (last_search_pattern[0] == '?') {
3525 dir = BACK;
3526 p = dot - 1;
3527 }
3528 dc4: 3512 dc4:
3529 q = char_search(p, last_search_pattern + 1, (dir << 1) | FULL); 3513 if (last_search_pattern[1] == '\0') {
3514 status_line_bold("No previous search");
3515 break;
3516 }
3517 do {
3518 q = char_search(dot + dir, last_search_pattern + 1,
3519 (dir << 1) | FULL);
3530 if (q != NULL) { 3520 if (q != NULL) {
3531 dot = q; // good search, update "dot" 3521 dot = q; // good search, update "dot"
3532 msg = NULL;
3533 goto dc2;
3534 }
3535 // no pattern found between "dot" and "end"- continue at top
3536 p = text;
3537 if (dir == BACK) {
3538 p = end - 1;
3539 }
3540 q = char_search(p, last_search_pattern + 1, (dir << 1) | FULL);
3541 if (q != NULL) { // found something
3542 dot = q; // found new pattern- goto it
3543 msg = "search hit BOTTOM, continuing at TOP";
3544 if (dir == BACK) {
3545 msg = "search hit TOP, continuing at BOTTOM";
3546 }
3547 } else { 3522 } else {
3548 msg = "Pattern not found"; 3523 // no pattern found between "dot" and top/bottom of file
3524 // continue from other end of file
3525 const char *msg;
3526 q = char_search(dir == FORWARD ? text : end - 1,
3527 last_search_pattern + 1, (dir << 1) | FULL);
3528 if (q != NULL) { // found something
3529 dot = q; // found new pattern- goto it
3530 msg = "search hit %s, continuing at %s";
3531 } else { // pattern is nowhere in file
3532 cmdcnt = 0; // force exit from loop
3533 msg = "Pattern not found";
3534 }
3535 if (dir == FORWARD)
3536 status_line_bold(msg, "BOTTOM", "TOP");
3537 else
3538 status_line_bold(msg, "TOP", "BOTTOM");
3549 } 3539 }
3550 dc2:
3551 if (msg)
3552 status_line_bold("%s", msg);
3553 } while (--cmdcnt > 0); 3540 } while (--cmdcnt > 0);
3554 break; 3541 break;
3555 case '{': // {- move backward paragraph 3542 case '{': // {- move backward paragraph