From 30e9673fdb22905df853ef07b3826fa19b28831c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Andr=C3=A9=20Tanner?= Date: Sat, 28 Nov 2015 18:37:29 +0100 Subject: vis: improve switching to prompt mode A call to vis_prompt_show will now automatically switch to prompt mode. Within the prompt leave/enter handlers the focused window (vis->win) will still point to the document window not the one referring to the prompt. The selection marks '< and '> are now only updated when a visual mode is left. --- main.c | 2 -- vis-modes.c | 26 ++++++++++++++++++++------ vis.c | 10 +++++----- vis.h | 2 +- 4 files changed, 26 insertions(+), 14 deletions(-) diff --git a/main.c b/main.c index f15882a..fc76f3c 100644 --- a/main.c +++ b/main.c @@ -1410,13 +1410,11 @@ static const char *insert_register(Vis *vis, const char *keys, const Arg *arg) { static const char *prompt_search(Vis *vis, const char *keys, const Arg *arg) { vis_prompt_show(vis, arg->s, ""); - vis_mode_switch(vis, VIS_MODE_PROMPT); return keys; } static const char *prompt_cmd(Vis *vis, const char *keys, const Arg *arg) { vis_prompt_show(vis, ":", arg->s); - vis_mode_switch(vis, VIS_MODE_PROMPT); return keys; } diff --git a/vis-modes.c b/vis-modes.c index 9da5009..f1f8343 100644 --- a/vis-modes.c +++ b/vis-modes.c @@ -64,16 +64,20 @@ static void vis_mode_operator_input(Vis *vis, const char *str, size_t len) { static void vis_mode_visual_enter(Vis *vis, Mode *old) { if (!old->visual) { - for (Cursor *c = view_cursors(vis->win->view); c; c = view_cursors_next(c)) - view_cursors_selection_start(c); + if (old != &vis_modes[VIS_MODE_PROMPT]) { + for (Cursor *c = view_cursors(vis->win->view); c; c = view_cursors_next(c)) + view_cursors_selection_start(c); + } vis_modes[VIS_MODE_OPERATOR].parent = &vis_modes[VIS_MODE_TEXTOBJ]; } } static void vis_mode_visual_line_enter(Vis *vis, Mode *old) { if (!old->visual) { - for (Cursor *c = view_cursors(vis->win->view); c; c = view_cursors_next(c)) - view_cursors_selection_start(c); + if (old != &vis_modes[VIS_MODE_PROMPT]) { + for (Cursor *c = view_cursors(vis->win->view); c; c = view_cursors_next(c)) + view_cursors_selection_start(c); + } vis_modes[VIS_MODE_OPERATOR].parent = &vis_modes[VIS_MODE_TEXTOBJ]; } vis_motion(vis, VIS_MOVE_LINE_END); @@ -81,8 +85,13 @@ 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) { - view_selections_clear(vis->win->view); vis_modes[VIS_MODE_OPERATOR].parent = &vis_modes[VIS_MODE_MOVE]; + File *file = vis->win->file; + Filerange sel = view_cursors_selection_get(view_cursors(vis->win->view)); + file->marks[MARK_SELECTION_START] = text_mark_set(file->text, sel.start); + file->marks[MARK_SELECTION_END] = text_mark_set(file->text, sel.end); + if (new != &vis_modes[VIS_MODE_PROMPT]) + view_selections_clear(vis->win->view); } else { view_cursor_to(vis->win->view, view_cursor_get(vis->win->view)); } @@ -90,8 +99,13 @@ static void vis_mode_visual_line_leave(Vis *vis, Mode *new) { static void vis_mode_visual_leave(Vis *vis, Mode *new) { if (!new->visual) { - view_selections_clear(vis->win->view); vis_modes[VIS_MODE_OPERATOR].parent = &vis_modes[VIS_MODE_MOVE]; + File *file = vis->win->file; + Filerange sel = view_cursors_selection_get(view_cursors(vis->win->view)); + file->marks[MARK_SELECTION_START] = text_mark_set(file->text, sel.start); + file->marks[MARK_SELECTION_END] = text_mark_set(file->text, sel.end); + if (new != &vis_modes[VIS_MODE_PROMPT]) + view_selections_clear(vis->win->view); } } diff --git a/vis.c b/vis.c index 1ab6e4e..c37dc28 100644 --- a/vis.c +++ b/vis.c @@ -462,9 +462,10 @@ void vis_prompt_show(Vis *vis, const char *title, const char *text) { if (vis->prompt_window) return; vis->prompt_window = vis->win; - vis->win = vis->prompt; vis->prompt_type = title[0]; vis->ui->prompt(vis->ui, title, text); + vis_mode_switch(vis, VIS_MODE_PROMPT); + vis->win = vis->prompt; } void vis_prompt_hide(Vis *vis) { @@ -544,7 +545,7 @@ static void action_do(Vis *vis, Action *a) { View *view = win->view; if (a->op == &ops[VIS_OP_FILTER] && !vis->mode->visual) - vis_mode_switch(vis, VIS_MODE_VISUAL); + vis_mode_switch(vis, VIS_MODE_VISUAL_LINE); if (a->count < 1) a->count = 1; @@ -671,11 +672,10 @@ static void action_do(Vis *vis, Action *a) { vis_mode_switch(vis, VIS_MODE_REPLACE); } else if (a->op == &ops[VIS_OP_FILTER]) { if (a->arg.s) { - if (vis_cmd(vis, a->arg.s)) - vis_mode_switch(vis, VIS_MODE_NORMAL); + vis_mode_switch(vis, VIS_MODE_NORMAL); + vis_cmd(vis, a->arg.s); } else { vis_prompt_show(vis, ":", "'<,'>!"); - vis_mode_switch(vis, VIS_MODE_PROMPT); } } else if (vis->mode == &vis_modes[VIS_MODE_OPERATOR]) { mode_set(vis, vis->mode_prev); diff --git a/vis.h b/vis.h index 2e8d584..0f984ed 100644 --- a/vis.h +++ b/vis.h @@ -106,7 +106,7 @@ void vis_exit(Vis*, int status); /* emergency exit, print given message, perform minimal ui cleanup and exit process */ void vis_die(Vis*, const char *msg, ...) __attribute__((noreturn)); -/* user facing modes are: NORMAL, VISUAL, VISUAL_LINE, PROMPT, INSERT, REPLACE. +/* user facing modes are: NORMAL, VISUAL, VISUAL_LINE, INSERT, REPLACE. * the others should be considered as implementation details (TODO: do not expose them?) */ enum VisMode { VIS_MODE_BASIC, -- cgit v1.2.3