aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config.def.h1
-rw-r--r--view.c26
-rw-r--r--view.h2
-rw-r--r--vis.c8
4 files changed, 35 insertions, 2 deletions
diff --git a/config.def.h b/config.def.h
index b8c7e7d..5da2ec3 100644
--- a/config.def.h
+++ b/config.def.h
@@ -433,6 +433,7 @@ static KeyBinding vis_mode_normal[] = {
{ { NONE('z'), NONE('b') }, window, { .w = view_redraw_bottom } },
{ { NONE('q') }, macro_record, { NULL } },
{ { NONE('@') }, macro_replay, { NULL } },
+ { { NONE('g'), NONE('v') }, selection_restore, { NULL } },
{ /* empty last element, array terminator */ },
};
diff --git a/view.c b/view.c
index cf579d2..b8b1dd6 100644
--- a/view.c
+++ b/view.c
@@ -41,6 +41,8 @@ struct Cursor { /* cursor position */
Line *line; /* screen line on which cursor currently resides */
Mark mark; /* mark used to keep track of current cursor position */
Selection *sel; /* selection (if any) which folows the cursor upon movement */
+ Mark lastsel_anchor;/* previously used selection data, */
+ Mark lastsel_cursor;/* used to restore it */
Register reg; /* per cursor register to support yank/put operation */
View *view; /* associated view to which this cursor belongs */
Cursor *prev, *next;/* previous/next cursors in no particular order */
@@ -994,6 +996,23 @@ void view_cursors_selection_start(Cursor *c) {
view_draw(c->view);
}
+void view_cursors_selection_restore(Cursor *c) {
+ Text *txt = c->view->text;
+ if (c->sel)
+ return;
+ Filerange sel = text_range_new(
+ text_mark_get(txt, c->lastsel_anchor),
+ text_mark_get(txt, c->lastsel_cursor)
+ );
+ if (!text_range_valid(&sel))
+ return;
+ if (!(c->sel = view_selections_new(c->view)))
+ return;
+ view_selections_set(c->sel, &sel);
+ view_cursors_selection_sync(c);
+ view_draw(c->view);
+}
+
void view_cursors_selection_stop(Cursor *c) {
c->sel = NULL;
}
@@ -1019,7 +1038,7 @@ void view_cursors_selection_sync(Cursor *c) {
bool right_extending = anchor < cursor;
if (right_extending)
cursor = text_char_prev(txt, cursor);
- cursor_to(c, cursor);
+ view_cursors_to(c, cursor);
}
Filerange view_cursors_selection_get(Cursor *c) {
@@ -1061,8 +1080,11 @@ void view_selections_free(Selection *s) {
s->view->selections = s->next;
// XXX: add backlink Selection->Cursor?
for (Cursor *c = s->view->cursors; c; c = c->next) {
- if (c->sel == s)
+ if (c->sel == s) {
+ c->lastsel_anchor = s->anchor;
+ c->lastsel_cursor = s->cursor;
c->sel = NULL;
+ }
}
free(s);
}
diff --git a/view.h b/view.h
index 69727c0..42b05c8 100644
--- a/view.h
+++ b/view.h
@@ -148,6 +148,8 @@ void view_cursors_selection_clear(Cursor*);
void view_cursors_selection_swap(Cursor*);
/* move cursor to the end/boundary of the associated selection */
void view_cursors_selection_sync(Cursor*);
+/* restore previous used selection of this cursor */
+void view_cursors_selection_restore(Cursor*);
/* get/set the selected region associated with this cursor */
Filerange view_cursors_selection_get(Cursor*);
void view_cursors_selection_set(Cursor*, Filerange*);
diff --git a/vis.c b/vis.c
index d6cbdbb..a4917e9 100644
--- a/vis.c
+++ b/vis.c
@@ -373,6 +373,8 @@ static void movement(const Arg *arg);
static void textobj(const Arg *arg);
/* move to the other end of selected text */
static void selection_end(const Arg *arg);
+/* restore least recently used selection */
+static void selection_restore(const Arg *arg);
/* use register indicated by arg->i for the current operator */
static void reg(const Arg *arg);
/* perform a movement to mark arg->i */
@@ -1075,6 +1077,12 @@ static void selection_end(const Arg *arg) {
view_cursors_selection_swap(c);
}
+static void selection_restore(const Arg *arg) {
+ for (Cursor *c = view_cursors(vis->win->view); c; c = view_cursors_next(c))
+ view_cursors_selection_restore(c);
+ switchmode(&(const Arg){ .i = VIS_MODE_VISUAL });
+}
+
static void reg(const Arg *arg) {
vis->action.reg = &vis->registers[arg->i];
}