aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config.def.h2
-rw-r--r--main.c21
-rw-r--r--view.c20
-rw-r--r--view.h10
-rw-r--r--vis-core.h1
-rw-r--r--vis-modes.c6
-rw-r--r--vis-registers.c3
-rw-r--r--vis.c22
-rw-r--r--vis.h1
9 files changed, 20 insertions, 66 deletions
diff --git a/config.def.h b/config.def.h
index 0ea03c9..e106b52 100644
--- a/config.def.h
+++ b/config.def.h
@@ -247,7 +247,7 @@ static const KeyBinding bindings_normal[] = {
{ "g+", ACTION(LATER) },
{ "gn", ALIAS("vgn") },
{ "gN", ALIAS("vgN") },
- { "gv", ACTION(SELECTION_RESTORE) },
+ { "gv", ALIAS("\"^Sv") },
{ "I", ACTION(INSERT_LINE_START) },
{ "i", ACTION(MODE_INSERT) },
{ "J", ACTION(JOIN_LINES) },
diff --git a/main.c b/main.c
index bbba81c..a9e9658 100644
--- a/main.c
+++ b/main.c
@@ -114,8 +114,6 @@ static const char *movement(Vis*, const char *keys, const Arg *arg);
static const char *textobj(Vis*, const char *keys, const Arg *arg);
/* move to the other end of selected text */
static const char *selection_end(Vis*, const char *keys, const Arg *arg);
-/* restore least recently used selection */
-static const char *selection_restore(Vis*, const char *keys, const Arg *arg);
/* use register indicated by keys for the current operator */
static const char *reg(Vis*, const char *keys, const Arg *arg);
/* perform arg->i motion with a mark indicated by keys as argument */
@@ -265,7 +263,6 @@ enum {
VIS_ACTION_PROMPT_SHOW,
VIS_ACTION_REPEAT,
VIS_ACTION_SELECTION_FLIP,
- VIS_ACTION_SELECTION_RESTORE,
VIS_ACTION_WINDOW_REDRAW_TOP,
VIS_ACTION_WINDOW_REDRAW_CENTER,
VIS_ACTION_WINDOW_REDRAW_BOTTOM,
@@ -913,11 +910,6 @@ static const KeyAction vis_action[] = {
VIS_HELP("Flip selection, move cursor to other end")
selection_end,
},
- [VIS_ACTION_SELECTION_RESTORE] = {
- "vis-selection-restore",
- VIS_HELP("Restore last selection")
- selection_restore,
- },
[VIS_ACTION_WINDOW_REDRAW_TOP] = {
"vis-window-redraw-top",
VIS_HELP("Redraw cursor line at the top of the window")
@@ -2025,19 +2017,6 @@ static const char *selection_end(Vis *vis, const char *keys, const Arg *arg) {
return keys;
}
-static const char *selection_restore(Vis *vis, const char *keys, const Arg *arg) {
- Text *txt = vis_text(vis);
- View *view = vis_view(vis);
- for (Selection *s = view_selections(view); s; s = view_selections_next(s))
- view_selections_restore(s);
- Filerange sel = view_selection_get(view);
- if (text_range_is_linewise(txt, &sel))
- vis_mode_switch(vis, VIS_MODE_VISUAL_LINE);
- else
- vis_mode_switch(vis, VIS_MODE_VISUAL);
- return keys;
-}
-
static const char *reg(Vis *vis, const char *keys, const Arg *arg) {
if (!keys[0])
return NULL;
diff --git a/view.c b/view.c
index 4a3e18c..40ae9f1 100644
--- a/view.c
+++ b/view.c
@@ -49,7 +49,6 @@ struct Selection {
Line *line; /* screen line on which cursor currently resides */
int generation; /* used to filter out newly created cursors during iteration */
int number; /* how many cursors are located before this one */
- SelectionRegion region; /* saved selection region */
View *view; /* associated view to which this cursor belongs */
Selection *prev, *next; /* previous/next cursors ordered by location at creation time */
};
@@ -1230,11 +1229,6 @@ bool view_selections_set(Selection *s, const Filerange *r) {
return true;
}
-void view_selections_save(Selection *s) {
- s->region.cursor = s->cursor;
- s->region.anchor = s->anchor;
-}
-
Filerange view_regions_restore(View *view, SelectionRegion *s) {
Text *txt = view->text;
size_t anchor = text_mark_get(txt, s->anchor);
@@ -1258,20 +1252,6 @@ bool view_regions_save(View *view, Filerange *r, SelectionRegion *s) {
return true;
}
-bool view_selections_restore(Selection *s) {
- Text *txt = s->view->text;
- size_t pos = text_mark_get(txt, s->region.cursor);
- if (pos == EPOS)
- return false;
- if (s->region.anchor != s->region.cursor && text_mark_get(txt, s->region.anchor) == EPOS)
- return false;
- s->cursor = s->region.cursor;
- s->anchor = s->region.anchor;
- s->anchored = true;
- view_cursors_to(s, pos);
- return true;
-}
-
void view_selections_set_all(View *view, Array *arr) {
Selection *s;
Filerange *r;
diff --git a/view.h b/view.h
index 4d473aa..60a41f9 100644
--- a/view.h
+++ b/view.h
@@ -346,16 +346,6 @@ Filerange view_selection_get(View*);
* @defgroup view_save
* @{
*/
-/** Save selection which can later be restored. */
-void view_selections_save(Selection*);
-/**
- * Restore a previously active selection.
- * @rst
- * .. note:: Fails if selection boundaries no longer exist.
- * @endrst
- */
-bool view_selections_restore(Selection*);
-
Filerange view_regions_restore(View*, SelectionRegion*);
bool view_regions_save(View*, Filerange*, SelectionRegion*);
/**
diff --git a/vis-core.h b/vis-core.h
index cd93096..8d95f97 100644
--- a/vis-core.h
+++ b/vis-core.h
@@ -162,6 +162,7 @@ struct Win {
View *view; /* currently displayed part of underlying text */
RingBuffer *jumplist; /* LRU jump management */
ChangeList changelist; /* state for iterating through least recently changes */
+ Register reg_selections;/* register used to store selections */
Mode modes[VIS_MODE_INVALID]; /* overlay mods used for per window key bindings */
Win *parent; /* window which was active when showing the command prompt */
Mode *parent_mode; /* mode which was active when showing the command prompt */
diff --git a/vis-modes.c b/vis-modes.c
index 6fd05b7..d6ea134 100644
--- a/vis-modes.c
+++ b/vis-modes.c
@@ -201,7 +201,8 @@ static void vis_mode_visual_line_enter(Vis *vis, Mode *old) {
static void vis_mode_visual_line_leave(Vis *vis, Mode *new) {
if (!new->visual) {
- window_selection_save(vis->win);
+ if (!vis->action.op)
+ window_selection_save(vis->win);
view_selections_clear_all(vis->win->view);
} else {
view_cursor_to(vis->win->view, view_cursor_get(vis->win->view));
@@ -210,7 +211,8 @@ static void vis_mode_visual_line_leave(Vis *vis, Mode *new) {
static void vis_mode_visual_leave(Vis *vis, Mode *new) {
if (!new->visual) {
- window_selection_save(vis->win);
+ if (!vis->action.op)
+ window_selection_save(vis->win);
view_selections_clear_all(vis->win->view);
}
}
diff --git a/vis-registers.c b/vis-registers.c
index 595bb5b..d20c76c 100644
--- a/vis-registers.c
+++ b/vis-registers.c
@@ -221,6 +221,8 @@ enum VisRegister vis_register_used(Vis *vis) {
}
static Register *register_from(Vis *vis, enum VisRegister id) {
+ if (id == VIS_REG_SELECTION && vis->win)
+ return &vis->win->reg_selections;
if (VIS_REG_A <= id && id <= VIS_REG_Z)
id = VIS_REG_a + id - VIS_REG_A;
if (id < LENGTH(vis->registers))
@@ -300,4 +302,5 @@ const RegisterDef vis_registers[] = {
[VIS_REG_COMMAND] = { ':', VIS_HELP("Last :-command") },
[VIS_REG_SHELL] = { '!', VIS_HELP("Last shell command given to either <, >, |, or !") },
[VIS_REG_NUMBER] = { '#', VIS_HELP("Register number") },
+ [VIS_REG_SELECTION] = { '^', VIS_HELP("Last selections") },
};
diff --git a/vis.c b/vis.c
index 969a74d..1e25a1b 100644
--- a/vis.c
+++ b/vis.c
@@ -246,14 +246,10 @@ void vis_window_status(Win *win, const char *status) {
void window_selection_save(Win *win) {
Vis *vis = win->vis;
- File *file = win->file;
- Filerange sel = view_selections_get(view_selections(win->view));
- file->marks[VIS_MARK_SELECTION_START] = text_mark_set(file->text, sel.start);
- file->marks[VIS_MARK_SELECTION_END] = text_mark_set(file->text, sel.end);
- if (!vis->action.op) {
- for (Selection *s = view_selections(win->view); s; s = view_selections_next(s))
- view_selections_save(s);
- }
+ View *view = win->view;
+ Array sel = view_selections_get_all(view);
+ vis_register_selections_set(vis, VIS_REG_SELECTION, &sel);
+ array_release(&sel);
}
static void window_free(Win *win) {
@@ -270,6 +266,7 @@ static void window_free(Win *win) {
for (size_t i = 0; i < LENGTH(win->modes); i++)
map_free(win->modes[i].bindings);
ringbuf_free(win->jumplist);
+ register_release(&win->reg_selections);
free(win);
}
@@ -467,6 +464,7 @@ Win *window_new_file(Vis *vis, File *file, enum UiOption options) {
window_free(win);
return NULL;
}
+ register_init(&win->reg_selections);
file->refcount++;
view_options_set(win->view, view_options_get(win->view));
view_tabwidth_set(win->view, vis->tabwidth);
@@ -845,6 +843,9 @@ void vis_do(Vis *vis) {
if (a->op == &vis_operators[VIS_OP_PUT_AFTER] && multiple_cursors && vis_register_count(vis, reg) == 1)
reg_slot = 0;
+ if (vis->mode->visual && a->op)
+ window_selection_save(win);
+
for (Selection *sel = view_selections(view), *next; sel; sel = next) {
if (vis->interrupted)
break;
@@ -982,11 +983,8 @@ void vis_do(Vis *vis) {
if (pos == EPOS) {
view_selections_dispose(sel);
} else if (pos <= text_size(txt)) {
- if (vis->mode->visual)
- view_selections_save(sel);
+ view_selection_clear(sel);
view_cursors_to(sel, pos);
- if (vis->mode->visual)
- view_selection_clear(sel);
}
}
}
diff --git a/vis.h b/vis.h
index 32dce80..4518b65 100644
--- a/vis.h
+++ b/vis.h
@@ -719,6 +719,7 @@ enum VisRegister {
VIS_REG_COMMAND, /* last used :-command ": */
VIS_REG_SHELL, /* last used shell command given to either <, >, |, or ! */
VIS_REG_NUMBER, /* cursor number */
+ VIS_REG_SELECTION, /* last used selections */
VIS_REG_a, VIS_REG_b, VIS_REG_c, VIS_REG_d, VIS_REG_e,
VIS_REG_f, VIS_REG_g, VIS_REG_h, VIS_REG_i, VIS_REG_j,
VIS_REG_k, VIS_REG_l, VIS_REG_m, VIS_REG_n, VIS_REG_o,