diff options
author | nicm <nicm> | 2020-03-31 16:53:23 +0000 |
---|---|---|
committer | Nicholas Marriott <nicholas.marriott@gmail.com> | 2020-04-01 10:08:09 +0100 |
commit | 8dedccaa205a91a0dd57012150567403c2ac827d (patch) | |
tree | 10568cade7d592df321d9dcd3c6abb25edcf3194 | |
parent | e5fd85415d89ebe8b2f69c80ce6cf80fb1442fde (diff) | |
download | rtmux-8dedccaa205a91a0dd57012150567403c2ac827d.tar.gz rtmux-8dedccaa205a91a0dd57012150567403c2ac827d.tar.bz2 rtmux-8dedccaa205a91a0dd57012150567403c2ac827d.zip |
Add non-regex search variants to avoid the performance cost for people
with large histories or long lines.
-rw-r--r-- | tmux.1 | 24 | ||||
-rw-r--r-- | tmux.h | 2 | ||||
-rw-r--r-- | window-copy.c | 135 |
3 files changed, 116 insertions, 45 deletions
@@ -1503,9 +1503,11 @@ The following commands are supported in copy mode: .It Li "scroll-up" Ta "C-y" Ta "C-Up" .It Li "search-again" Ta "n" Ta "n" .It Li "search-backward <for>" Ta "?" Ta "" -.It Li "search-forward <for>" Ta "/" Ta "" .It Li "search-backward-incremental <for>" Ta "" Ta "C-r" +.It Li "search-backward-text <for>" Ta "" Ta "" +.It Li "search-forward <for>" Ta "/" Ta "" .It Li "search-forward-incremental <for>" Ta "" Ta "C-s" +.It Li "search-forward-text <for>" Ta "" Ta "" .It Li "search-reverse" Ta "N" Ta "N" .It Li "select-line" Ta "V" Ta "" .It Li "select-word" Ta "" Ta "" @@ -1514,6 +1516,26 @@ The following commands are supported in copy mode: .It Li "top-line" Ta "H" Ta "M-R" .El .Pp +The search commands come in several varieties: +.Ql search-forward +and +.Ql search-backward +search for a regular expression; +the +.Ql -text +variants search for a plain text string rather than a regular expression; +.Ql -incremental +perform an incremental search and expect to be used with the +.Fl i +flag to the +.Ic command-prompt +command. +.Ql search-again +repeats the last search and +.Ql search-reverse +does the same but reverses the direction (forward becomes backward and backward +becomes forward). +.Pp Copy commands may take an optional buffer prefix argument which is used to generate the buffer name (the default is .Ql buffer @@ -927,7 +927,9 @@ struct window_pane { TAILQ_HEAD (, window_mode_entry) modes; struct event modetimer; time_t modelast; + char *searchstr; + int searchregex; TAILQ_ENTRY(window_pane) entry; RB_ENTRY(window_pane) tree_entry; diff --git a/window-copy.c b/window-copy.c index 8e3f63d1..bb38e60e 100644 --- a/window-copy.c +++ b/window-copy.c @@ -254,6 +254,7 @@ struct window_copy_mode_data { u_int lastsx; /* size of last line w/ content */ int searchtype; + int searchregex; char *searchstr; bitstr_t *searchmark; u_int searchcount; @@ -307,9 +308,11 @@ window_copy_common_init(struct window_mode_entry *wme) if (wp->searchstr != NULL) { data->searchtype = WINDOW_COPY_SEARCHUP; + data->searchregex = wp->searchregex; data->searchstr = xstrdup(wp->searchstr); } else { data->searchtype = WINDOW_COPY_OFF; + data->searchregex = 0; data->searchstr = NULL; } data->searchmark = NULL; @@ -675,6 +678,35 @@ window_copy_key_table(struct window_mode_entry *wme) return ("copy-mode"); } +static int +window_copy_expand_search_string(struct window_copy_cmd_state *cs) +{ + struct window_mode_entry *wme = cs->wme; + struct window_copy_mode_data *data = wme->data; + const char *argument; + char *expanded; + + if (cs->args->argc == 2) { + argument = cs->args->argv[1]; + if (*argument != '\0') { + if (args_has(cs->args, 'F')) { + expanded = format_single(NULL, argument, NULL, + NULL, NULL, wme->wp); + if (*expanded == '\0') { + free(expanded); + return (0); + } + free(data->searchstr); + data->searchstr = expanded; + } else { + free(data->searchstr); + data->searchstr = xstrdup(argument); + } + } + } + return (1); +} + static enum window_copy_cmd_action window_copy_cmd_append_selection(struct window_copy_cmd_state *cs) { @@ -1496,10 +1528,10 @@ window_copy_cmd_search_again(struct window_copy_cmd_state *cs) if (data->searchtype == WINDOW_COPY_SEARCHUP) { for (; np != 0; np--) - window_copy_search_up(wme, 1); + window_copy_search_up(wme, data->searchregex); } else if (data->searchtype == WINDOW_COPY_SEARCHDOWN) { for (; np != 0; np--) - window_copy_search_down(wme, 1); + window_copy_search_down(wme, data->searchregex); } return (WINDOW_COPY_CMD_NOTHING); } @@ -1513,10 +1545,10 @@ window_copy_cmd_search_reverse(struct window_copy_cmd_state *cs) if (data->searchtype == WINDOW_COPY_SEARCHUP) { for (; np != 0; np--) - window_copy_search_down(wme, 1); + window_copy_search_down(wme, data->searchregex); } else if (data->searchtype == WINDOW_COPY_SEARCHDOWN) { for (; np != 0; np--) - window_copy_search_up(wme, 1); + window_copy_search_up(wme, data->searchregex); } return (WINDOW_COPY_CMD_NOTHING); } @@ -1736,29 +1768,13 @@ window_copy_cmd_search_backward(struct window_copy_cmd_state *cs) struct window_mode_entry *wme = cs->wme; struct window_copy_mode_data *data = wme->data; u_int np = wme->prefix; - const char *argument; - char *expanded; - if (cs->args->argc == 2) { - argument = cs->args->argv[1]; - if (*argument != '\0') { - if (args_has(cs->args, 'F')) { - expanded = format_single(NULL, argument, NULL, - NULL, NULL, wme->wp); - if (*expanded == '\0') { - free(expanded); - return (WINDOW_COPY_CMD_NOTHING); - } - free(data->searchstr); - data->searchstr = expanded; - } else { - free(data->searchstr); - data->searchstr = xstrdup(argument); - } - } - } + if (!window_copy_expand_search_string(cs)) + return (WINDOW_COPY_CMD_NOTHING); + if (data->searchstr != NULL) { data->searchtype = WINDOW_COPY_SEARCHUP; + data->searchregex = 1; for (; np != 0; np--) window_copy_search_up(wme, 1); } @@ -1766,34 +1782,37 @@ window_copy_cmd_search_backward(struct window_copy_cmd_state *cs) } static enum window_copy_cmd_action -window_copy_cmd_search_forward(struct window_copy_cmd_state *cs) +window_copy_cmd_search_backward_text(struct window_copy_cmd_state *cs) { struct window_mode_entry *wme = cs->wme; struct window_copy_mode_data *data = wme->data; u_int np = wme->prefix; - const char *argument; - char *expanded; - if (cs->args->argc == 2) { - argument = cs->args->argv[1]; - if (*argument != '\0') { - if (args_has(cs->args, 'F')) { - expanded = format_single(NULL, argument, NULL, - NULL, NULL, wme->wp); - if (*expanded == '\0') { - free(expanded); - return (WINDOW_COPY_CMD_NOTHING); - } - free(data->searchstr); - data->searchstr = expanded; - } else { - free(data->searchstr); - data->searchstr = xstrdup(argument); - } - } + if (!window_copy_expand_search_string(cs)) + return (WINDOW_COPY_CMD_NOTHING); + + if (data->searchstr != NULL) { + data->searchtype = WINDOW_COPY_SEARCHUP; + data->searchregex = 0; + for (; np != 0; np--) + window_copy_search_up(wme, 0); } + return (WINDOW_COPY_CMD_NOTHING); +} + +static enum window_copy_cmd_action +window_copy_cmd_search_forward(struct window_copy_cmd_state *cs) +{ + struct window_mode_entry *wme = cs->wme; + struct window_copy_mode_data *data = wme->data; + u_int np = wme->prefix; + + if (!window_copy_expand_search_string(cs)) + return (WINDOW_COPY_CMD_NOTHING); + if (data->searchstr != NULL) { data->searchtype = WINDOW_COPY_SEARCHDOWN; + data->searchregex = 1; for (; np != 0; np--) window_copy_search_down(wme, 1); } @@ -1801,6 +1820,25 @@ window_copy_cmd_search_forward(struct window_copy_cmd_state *cs) } static enum window_copy_cmd_action +window_copy_cmd_search_forward_text(struct window_copy_cmd_state *cs) +{ + struct window_mode_entry *wme = cs->wme; + struct window_copy_mode_data *data = wme->data; + u_int np = wme->prefix; + + if (!window_copy_expand_search_string(cs)) + return (WINDOW_COPY_CMD_NOTHING); + + if (data->searchstr != NULL) { + data->searchtype = WINDOW_COPY_SEARCHDOWN; + data->searchregex = 0; + for (; np != 0; np--) + window_copy_search_down(wme, 0); + } + return (WINDOW_COPY_CMD_NOTHING); +} + +static enum window_copy_cmd_action window_copy_cmd_search_backward_incremental(struct window_copy_cmd_state *cs) { struct window_mode_entry *wme = cs->wme; @@ -1829,6 +1867,7 @@ window_copy_cmd_search_backward_incremental(struct window_copy_cmd_state *cs) case '=': case '-': data->searchtype = WINDOW_COPY_SEARCHUP; + data->searchregex = 0; free(data->searchstr); data->searchstr = xstrdup(argument); if (!window_copy_search_up(wme, 0)) { @@ -1838,6 +1877,7 @@ window_copy_cmd_search_backward_incremental(struct window_copy_cmd_state *cs) break; case '+': data->searchtype = WINDOW_COPY_SEARCHDOWN; + data->searchregex = 0; free(data->searchstr); data->searchstr = xstrdup(argument); if (!window_copy_search_down(wme, 0)) { @@ -1878,6 +1918,7 @@ window_copy_cmd_search_forward_incremental(struct window_copy_cmd_state *cs) case '=': case '+': data->searchtype = WINDOW_COPY_SEARCHDOWN; + data->searchregex = 0; free(data->searchstr); data->searchstr = xstrdup(argument); if (!window_copy_search_down(wme, 0)) { @@ -1887,6 +1928,7 @@ window_copy_cmd_search_forward_incremental(struct window_copy_cmd_state *cs) break; case '-': data->searchtype = WINDOW_COPY_SEARCHUP; + data->searchregex = 0; free(data->searchstr); data->searchstr = xstrdup(argument); if (!window_copy_search_up(wme, 0)) { @@ -2012,10 +2054,14 @@ static const struct { window_copy_cmd_search_again }, { "search-backward", 0, 1, 0, window_copy_cmd_search_backward }, + { "search-backward-text", 0, 1, 0, + window_copy_cmd_search_backward_text }, { "search-backward-incremental", 1, 1, 0, window_copy_cmd_search_backward_incremental }, { "search-forward", 0, 1, 0, window_copy_cmd_search_forward }, + { "search-forward-text", 0, 1, 0, + window_copy_cmd_search_forward_text }, { "search-forward-incremental", 1, 1, 0, window_copy_cmd_search_forward_incremental }, { "search-reverse", 0, 0, 0, @@ -2624,6 +2670,7 @@ window_copy_search(struct window_mode_entry *wme, int direction, int regex) free(wp->searchstr); wp->searchstr = xstrdup(data->searchstr); + wp->searchregex = regex; fx = data->cx; fy = screen_hsize(data->backing) - data->oy + data->cy; |