vis
a vi-like editor based on Plan 9's structural regular expressions
git clone https://9o.is/git/vis.git
commit c4059aca95bdccbb95c815b52e528c130b1da415 parent 0d4e4a9f2079e6ca188786202bc1438cc58322a5 Author: Marc André Tanner <mat@brain-dump.org> Date: Mon, 3 Feb 2020 14:25:02 +0100 vis: improve <C-n> in visual mode If the existing primary selection is not a word, switch to a literal search. This should still avoid unwanted prefix matches (e.g. when renaming related variables) but allow searching for arbitrary regions. Fix #746 Diffstat:
| M | main.c | | | 38 | +++++++++++++++++++++++++++++++++++++- |
1 file changed, 37 insertions(+), 1 deletion(-)
diff --git a/main.c b/main.c @@ -1397,6 +1397,37 @@ static const Selection *selection_new_primary(View *view, Filerange *r) { return s; } +static const char *selections_match_next_literal(Vis *vis, const char *keys, const Arg *arg) { + Text *txt = vis_text(vis); + View *view = vis_view(vis); + Selection *s = view_selections_primary_get(view); + Filerange sel = view_selections_get(s); + size_t len = text_range_size(&sel); + if (!len) + return keys; + + char *buf = text_bytes_alloc0(txt, sel.start, len); + if (!buf) + return keys; + + size_t start = text_find_next(txt, sel.end, buf); + Filerange match = text_range_new(start, start+len); + if (start != sel.end && selection_new_primary(view, &match)) + goto out; + + sel = view_selections_get(view_selections(view)); + start = text_find_prev(txt, sel.start, buf); + if (start == sel.start) + goto out; + + match = text_range_new(start, start+len); + selection_new_primary(view, &match); + +out: + free(buf); + return keys; +} + static const char *selections_match_next(Vis *vis, const char *keys, const Arg *arg) { Text *txt = vis_text(vis); View *view = vis_view(vis); @@ -1405,10 +1436,15 @@ static const char *selections_match_next(Vis *vis, const char *keys, const Arg * if (!text_range_valid(&sel)) return keys; + Filerange word = text_object_word(txt, view_cursors_pos(s)); + if (!text_range_equal(&sel, &word)) + return selections_match_next_literal(vis, keys, arg); + char *buf = text_bytes_alloc0(txt, sel.start, text_range_size(&sel)); if (!buf) return keys; - Filerange word = text_object_word_find_next(txt, sel.end, buf); + + word = text_object_word_find_next(txt, sel.end, buf); if (text_range_valid(&word) && selection_new_primary(view, &word)) goto out;