Skip to content

Commit

Permalink
vis: implement union of selections
Browse files Browse the repository at this point in the history
  • Loading branch information
martanne committed Jun 15, 2017
1 parent e0be1ee commit 512155c
Showing 1 changed file with 59 additions and 0 deletions.
59 changes: 59 additions & 0 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ static const char *selections_trim(Vis*, const char *keys, const Arg *arg);
static const char *selections_save(Vis*, const char *keys, const Arg *arg);
/* restore selections from register */
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);
/* 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)
Expand Down Expand Up @@ -282,6 +284,7 @@ enum {
VIS_ACTION_SELECTIONS_TRIM,
VIS_ACTION_SELECTIONS_SAVE,
VIS_ACTION_SELECTIONS_RESTORE,
VIS_ACTION_SELECTIONS_UNION,
VIS_ACTION_TEXT_OBJECT_WORD_OUTER,
VIS_ACTION_TEXT_OBJECT_WORD_INNER,
VIS_ACTION_TEXT_OBJECT_LONGWORD_OUTER,
Expand Down Expand Up @@ -1052,6 +1055,11 @@ static const KeyAction vis_action[] = {
VIS_HELP("Restore selections from register")
selections_restore
},
[VIS_ACTION_SELECTIONS_UNION] = {
"vis-selections-union",
VIS_HELP("Add selections from register")
selections_union
},
[VIS_ACTION_TEXT_OBJECT_WORD_OUTER] = {
"vis-textobject-word-outer",
VIS_HELP("A word leading and trailing whitespace included")
Expand Down Expand Up @@ -1612,6 +1620,57 @@ static const char *selections_restore(Vis *vis, const char *keys, const Arg *arg
return keys;
}

static const char *selections_union(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);

size_t i = 0, j = 0;
Filerange *r1 = array_get(&a, i), *r2 = array_get(&b, j), cur = text_range_empty();
while (r1 || r2) {
if (r1 && text_range_overlap(r1, &cur)) {
cur = text_range_union(r1, &cur);
r1 = array_get(&a, ++i);
} else if (r2 && text_range_overlap(r2, &cur)) {
cur = text_range_union(r2, &cur);
r2 = array_get(&b, ++j);
} else {
if (text_range_valid(&cur))
array_add(&sel, &cur);
if (!r1) {
cur = *r2;
r2 = array_get(&b, ++j);
} else if (!r2) {
cur = *r1;
r1 = array_get(&a, ++i);
} else {
if (r1->start < r2->start) {
cur = *r1;
r1 = array_get(&a, ++i);
} else {
cur = *r2;
r2 = array_get(&b, ++j);
}
}
}
}

if (text_range_valid(&cur))
array_add(&sel, &cur);

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);
Expand Down

0 comments on commit 512155c

Please sign in to comment.