diff options
-rw-r--r-- | editors/vi.c | 85 |
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 |