diff options
| author | Marc André Tanner <mat@brain-dump.org> | 2017-06-15 12:05:49 +0200 |
|---|---|---|
| committer | Marc André Tanner <mat@brain-dump.org> | 2017-06-15 15:51:43 +0200 |
| commit | f34cdca6a804182198b9f833c51bed78b3101a51 (patch) | |
| tree | ae64eb5570ef003167025e21985b4bb7b4740c36 | |
| parent | 512155c08e853ae4267f15e9cf7972328a351b0b (diff) | |
| download | vis-f34cdca6a804182198b9f833c51bed78b3101a51.tar.gz vis-f34cdca6a804182198b9f833c51bed78b3101a51.tar.xz | |
vis: implement intersection of selections
| -rw-r--r-- | main.c | 42 |
1 files changed, 42 insertions, 0 deletions
@@ -80,6 +80,8 @@ static const char *selections_save(Vis*, const char *keys, const Arg *arg); static const char *selections_restore(Vis*, const char *keys, const Arg *arg); /* union selections */ static const char *selections_union(Vis*, const char *keys, const Arg *arg); +/* intersect selections */ +static const char *selections_intersect(Vis*, const char *keys, const Arg *arg); /* adjust current used count according to keys */ static const char *count(Vis*, const char *keys, const Arg *arg); /* move to the count-th line or if not given either to the first (arg->i < 0) @@ -285,6 +287,7 @@ enum { VIS_ACTION_SELECTIONS_SAVE, VIS_ACTION_SELECTIONS_RESTORE, VIS_ACTION_SELECTIONS_UNION, + VIS_ACTION_SELECTIONS_INTERSECT, VIS_ACTION_TEXT_OBJECT_WORD_OUTER, VIS_ACTION_TEXT_OBJECT_WORD_INNER, VIS_ACTION_TEXT_OBJECT_LONGWORD_OUTER, @@ -1060,6 +1063,11 @@ static const KeyAction vis_action[] = { VIS_HELP("Add selections from register") selections_union }, + [VIS_ACTION_SELECTIONS_INTERSECT] = { + "vis-selections-intersect", + VIS_HELP("Intersect selections with register") + selections_intersect + }, [VIS_ACTION_TEXT_OBJECT_WORD_OUTER] = { "vis-textobject-word-outer", VIS_HELP("A word leading and trailing whitespace included") @@ -1671,6 +1679,40 @@ static const char *selections_union(Vis *vis, const char *keys, const Arg *arg) return keys; } +static void intersect(Array *ret, Array *a, Array *b) { + size_t i = 0, j = 0; + Filerange *r1 = array_get(a, i), *r2 = array_get(b, j); + while (r1 && r2) { + if (text_range_overlap(r1, r2)) { + Filerange new = text_range_intersect(r1, r2); + array_add(ret, &new); + } + if (r1->end < r2->end) + r1 = array_get(a, ++i); + else + r2 = array_get(b, ++j); + } +} + +static const char *selections_intersect(Vis *vis, const char *keys, const Arg *arg) { + View *view = vis_view(vis); + enum VisRegister reg = vis_register_used(vis); + Array a = vis_register_selections_get(vis, reg); + Array b = view_selections_get_all(view); + Array sel; + array_init_from(&sel, &a); + + intersect(&sel, &a, &b); + view_selections_set_all(view, &sel); + vis_cancel(vis); + + array_release(&a); + array_release(&b); + array_release(&sel); + + return keys; +} + static const char *replace(Vis *vis, const char *keys, const Arg *arg) { if (!keys[0]) { vis_keymap_disable(vis); |
