summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston2021-04-06 13:39:48 +0100
committerDenys Vlasenko2021-04-11 00:18:55 +0200
commit7ce0e75c1f26d9cb3061c64aeab3204f62a5b55c (patch)
tree403b55810b02141f10a15da7fd063be53870b71e
parent9f017d9db0eb5522eb9c140a2d839461c677eb8e (diff)
downloadbusybox-7ce0e75c1f26d9cb3061c64aeab3204f62a5b55c.zip
busybox-7ce0e75c1f26d9cb3061c64aeab3204f62a5b55c.tar.gz
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 1c5a32b..5dc14f1 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -3486,70 +3486,57 @@ static void do_cmd(int c)
break;
#endif
#if ENABLE_FEATURE_VI_SEARCH
- case '?': // /- search for a pattern
- case '/': // /- search for a pattern
+ case 'N': // N- backward search for last pattern
+ dir = last_search_pattern[0] == '/' ? BACK : FORWARD;
+ goto dc4; // now search for pattern
+ break;
+ case '?': // ?- backward search for a pattern
+ case '/': // /- forward search for a pattern
buf[0] = c;
buf[1] = '\0';
q = get_input_line(buf); // get input line- use "status line"
- if (q[0] && !q[1]) {
+ if (!q[0]) // user changed mind and erased the "/"- do nothing
+ break;
+ if (!q[1]) { // if no pat re-use old pat
if (last_search_pattern[0])
last_search_pattern[0] = c;
- goto dc3; // if no pat re-use old pat
- }
- if (q[0]) { // strlen(q) > 1: new pat- save it and find
- // there is a new pat
+ } else { // strlen(q) > 1: new pat- save it and find
free(last_search_pattern);
last_search_pattern = xstrdup(q);
- goto dc3; // now find the pattern
}
- // user changed mind and erased the "/"- do nothing
- break;
- case 'N': // N- backward search for last pattern
- dir = BACK; // assume BACKWARD search
- p = dot - 1;
- if (last_search_pattern[0] == '?') {
- dir = FORWARD;
- p = dot + 1;
- }
- goto dc4; // now search for pattern
- break;
+ // fall through
case 'n': // n- repeat search for last pattern
// search rest of text[] starting at next char
- // if search fails return orignal "p" not the "p+1" address
- do {
- const char *msg;
- dc3:
- dir = FORWARD; // assume FORWARD search
- p = dot + 1;
- if (last_search_pattern[0] == '?') {
- dir = BACK;
- p = dot - 1;
- }
+ // if search fails "dot" is unchanged
+ dir = last_search_pattern[0] == '/' ? FORWARD : BACK;
dc4:
- q = char_search(p, last_search_pattern + 1, (dir << 1) | FULL);
+ if (last_search_pattern[1] == '\0') {
+ status_line_bold("No previous search");
+ break;
+ }
+ do {
+ q = char_search(dot + dir, last_search_pattern + 1,
+ (dir << 1) | FULL);
if (q != NULL) {
dot = q; // good search, update "dot"
- msg = NULL;
- goto dc2;
- }
- // no pattern found between "dot" and "end"- continue at top
- p = text;
- if (dir == BACK) {
- p = end - 1;
- }
- q = char_search(p, last_search_pattern + 1, (dir << 1) | FULL);
- if (q != NULL) { // found something
- dot = q; // found new pattern- goto it
- msg = "search hit BOTTOM, continuing at TOP";
- if (dir == BACK) {
- msg = "search hit TOP, continuing at BOTTOM";
- }
} else {
- msg = "Pattern not found";
+ // no pattern found between "dot" and top/bottom of file
+ // continue from other end of file
+ const char *msg;
+ q = char_search(dir == FORWARD ? text : end - 1,
+ last_search_pattern + 1, (dir << 1) | FULL);
+ if (q != NULL) { // found something
+ dot = q; // found new pattern- goto it
+ msg = "search hit %s, continuing at %s";
+ } else { // pattern is nowhere in file
+ cmdcnt = 0; // force exit from loop
+ msg = "Pattern not found";
+ }
+ if (dir == FORWARD)
+ status_line_bold(msg, "BOTTOM", "TOP");
+ else
+ status_line_bold(msg, "TOP", "BOTTOM");
}
- dc2:
- if (msg)
- status_line_bold("%s", msg);
} while (--cmdcnt > 0);
break;
case '{': // {- move backward paragraph