diff options
| -rw-r--r-- | config.def.h | 1 | ||||
| -rw-r--r-- | view.c | 26 | ||||
| -rw-r--r-- | view.h | 2 | ||||
| -rw-r--r-- | vis.c | 8 |
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 */ }, }; @@ -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); } @@ -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*); @@ -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]; } |
