From 08aee6721db1b1eba6f9e2d58b4e4ffe37a9ecd1 Mon Sep 17 00:00:00 2001 From: Evan Gates Date: Fri, 25 Sep 2020 11:31:17 -0700 Subject: vis: add vis-selection-new-match-all Add new vis-selection-new-match-all command, default keybinding in visual mode. Refactor selections_next_match to find all matches if arg.b is true. This does not affect existing configs as arg.b defaults to false. --- config.def.h | 1 + main.c | 38 ++++++++++++++++++++++++++++---------- man/vis.1 | 3 +++ 3 files changed, 32 insertions(+), 10 deletions(-) diff --git a/config.def.h b/config.def.h index 6a4555e..61b97b3 100644 --- a/config.def.h +++ b/config.def.h @@ -243,6 +243,7 @@ static const KeyBinding bindings_visual[] = { { "+", ACTION(SELECTIONS_ROTATE_RIGHT) }, { "<", ALIAS("gv") }, { ">", ALIAS("gv") }, + { "", ACTION(SELECTIONS_NEW_MATCH_ALL) }, { "", ALIAS("") }, { "", ACTION(SELECTIONS_REMOVE_COLUMN) }, { "", ACTION(SELECTIONS_NEXT) }, diff --git a/main.c b/main.c index a740697..ce14d3f 100644 --- a/main.c +++ b/main.c @@ -260,6 +260,7 @@ enum { VIS_ACTION_SELECTIONS_NEW_LINE_BELOW_LAST, VIS_ACTION_SELECTIONS_NEW_LINES_BEGIN, VIS_ACTION_SELECTIONS_NEW_LINES_END, + VIS_ACTION_SELECTIONS_NEW_MATCH_ALL, VIS_ACTION_SELECTIONS_NEW_MATCH_NEXT, VIS_ACTION_SELECTIONS_NEW_MATCH_SKIP, VIS_ACTION_SELECTIONS_ALIGN, @@ -917,6 +918,11 @@ static const KeyAction vis_action[] = { VIS_HELP("Create a new selection at the end of every line covered by selection") operator, { .i = VIS_OP_CURSOR_EOL } }, + [VIS_ACTION_SELECTIONS_NEW_MATCH_ALL] = { + "vis-selection-new-match-all", + VIS_HELP("Select all regions matching the current selection") + selections_match_next, { .b = true } + }, [VIS_ACTION_SELECTIONS_NEW_MATCH_NEXT] = { "vis-selection-new-match-next", VIS_HELP("Select the next region matching the current selection") @@ -1325,7 +1331,7 @@ static const char *selections_clear(Vis *vis, const char *keys, const Arg *arg) return keys; } -static const Selection *selection_new_primary(View *view, Filerange *r) { +static Selection *selection_new(View *view, Filerange *r, bool isprimary) { Text *txt = view_text(view); size_t pos = text_char_prev(txt, r->end); Selection *s = view_selections_new(view, pos); @@ -1333,7 +1339,8 @@ static const Selection *selection_new_primary(View *view, Filerange *r) { return NULL; view_selections_set(s, r); view_selections_anchor(s, true); - view_selections_primary_set(s); + if (isprimary) + view_selections_primary_set(s); return s; } @@ -1363,15 +1370,26 @@ static const char *selections_match_next(Vis *vis, const char *keys, const Arg * if (!buf) return keys; - Filerange word = find_next(txt, sel.end, buf); - if (text_range_valid(&word) && selection_new_primary(view, &word)) - goto out; + bool match_all = arg->b; + Filerange primary = sel; + + for (;;) { + sel = find_next(txt, sel.end, buf); + if (!text_range_valid(&sel)) + break; + if (selection_new(view, &sel, !match_all) && !match_all) + goto out; + } - sel = view_selections_get(view_selections(view)); - word = find_prev(txt, sel.start, buf); - if (!text_range_valid(&word)) - goto out; - selection_new_primary(view, &word); + sel = primary; + + for (;;) { + sel = find_prev(txt, sel.start, buf); + if (!text_range_valid(&sel)) + break; + if (selection_new(view, &sel, !match_all) && !match_all) + break; + } out: free(buf); diff --git a/man/vis.1 b/man/vis.1 index 10ad5bb..4082997 100644 --- a/man/vis.1 +++ b/man/vis.1 @@ -1097,6 +1097,9 @@ left align selections by inserting spaces .It Aq Ic S-Tab right align selections by inserting spaces . +.It Aq Ic C-a +create new selections everywhere matching current word or selection +. .It Aq Ic C-n create new selection and select next word matching current selection . -- cgit v1.2.3