Skip to content

Commit

Permalink
vis: implement gv by means of new "^ register
Browse files Browse the repository at this point in the history
This window local register holds the last active selections.
  • Loading branch information
martanne committed Jul 3, 2017
1 parent 54ca598 commit bfb9071
Show file tree
Hide file tree
Showing 9 changed files with 20 additions and 66 deletions.
2 changes: 1 addition & 1 deletion config.def.h
Original file line number Diff line number Diff line change
Expand Up @@ -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) },
Expand Down
21 changes: 0 additions & 21 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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")
Expand Down Expand Up @@ -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;
Expand Down
20 changes: 0 additions & 20 deletions view.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
};
Expand Down Expand Up @@ -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);
Expand All @@ -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;
Expand Down
10 changes: 0 additions & 10 deletions view.h
Original file line number Diff line number Diff line change
Expand Up @@ -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*);
/**
Expand Down
1 change: 1 addition & 0 deletions vis-core.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
6 changes: 4 additions & 2 deletions vis-modes.c
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand All @@ -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);
}
}
Expand Down
3 changes: 3 additions & 0 deletions vis-registers.c
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down Expand Up @@ -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") },
};
22 changes: 10 additions & 12 deletions vis.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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);
}

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
}
}
Expand Down
1 change: 1 addition & 0 deletions vis.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit bfb9071

Please sign in to comment.