aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2014-10-25 11:43:29 +0200
committerMarc André Tanner <mat@brain-dump.org>2014-10-25 15:32:49 +0200
commitecce157aeb21226266e718472e610d9a0a696fd4 (patch)
treec1908d529134e662d41c3f7ae192de73b5f1759b
parent1b55dc64b529ceab804a87649a55714fb2ff5973 (diff)
downloadvis-ecce157aeb21226266e718472e610d9a0a696fd4.tar.gz
vis-ecce157aeb21226266e718472e610d9a0a696fd4.tar.xz
Fix mode switching bugs
-rw-r--r--config.def.h16
-rw-r--r--vis.c11
-rw-r--r--window.c2
3 files changed, 22 insertions, 7 deletions
diff --git a/config.def.h b/config.def.h
index 0e81845..4a9ac9a 100644
--- a/config.def.h
+++ b/config.def.h
@@ -493,10 +493,13 @@ static void vis_mode_prompt_input(const char *str, size_t len) {
editor_insert_key(vis, str, len);
}
+static void vis_mode_prompt_enter(Mode *old) {
+ if (old->isuser && old != &vis_modes[VIS_MODE_PROMPT])
+ mode_before_prompt = old;
+}
+
static void vis_mode_prompt_leave(Mode *new) {
- /* prompt mode may be left for operator mode when editing the command prompt.
- * for example during Ctrl+w / delete_word. don't hide the prompt in this case */
- if (new != &vis_modes[VIS_MODE_OPERATOR])
+ if (new->isuser)
editor_prompt_hide(vis);
}
@@ -681,11 +684,13 @@ static Mode vis_modes[] = {
},
[VIS_MODE_NORMAL] = {
.name = "NORMAL",
+ .isuser = true,
.parent = &vis_modes[VIS_MODE_MARK_SET],
.bindings = vis_mode_normal,
},
[VIS_MODE_VISUAL] = {
.name = "--VISUAL--",
+ .isuser = true,
.parent = &vis_modes[VIS_MODE_REGISTER],
.bindings = vis_mode_visual,
.enter = vis_mode_visual_enter,
@@ -694,6 +699,7 @@ static Mode vis_modes[] = {
},
[VIS_MODE_VISUAL_LINE] = {
.name = "--VISUAL LINE--",
+ .isuser = true,
.parent = &vis_modes[VIS_MODE_VISUAL],
.bindings = vis_mode_visual_line,
.enter = vis_mode_visual_line_enter,
@@ -707,9 +713,11 @@ static Mode vis_modes[] = {
},
[VIS_MODE_PROMPT] = {
.name = "PROMPT",
+ .isuser = true,
.parent = &vis_modes[VIS_MODE_READLINE],
.bindings = vis_mode_prompt,
.input = vis_mode_prompt_input,
+ .enter = vis_mode_prompt_enter,
.leave = vis_mode_prompt_leave,
},
[VIS_MODE_INSERT_REGISTER] = {
@@ -720,6 +728,7 @@ static Mode vis_modes[] = {
},
[VIS_MODE_INSERT] = {
.name = "--INSERT--",
+ .isuser = true,
.parent = &vis_modes[VIS_MODE_INSERT_REGISTER],
.bindings = vis_mode_insert,
.leave = vis_mode_insert_leave,
@@ -729,6 +738,7 @@ static Mode vis_modes[] = {
},
[VIS_MODE_REPLACE] = {
.name = "--REPLACE--",
+ .isuser = true,
.parent = &vis_modes[VIS_MODE_INSERT],
.bindings = vis_mode_replace,
.leave = vis_mode_replace_leave,
diff --git a/vis.c b/vis.c
index b9bc488..6df1f5a 100644
--- a/vis.c
+++ b/vis.c
@@ -64,6 +64,7 @@ struct Mode {
Mode *parent; /* if no match is found in this mode, search will continue there */
KeyBinding *bindings; /* NULL terminated array of keybindings for this mode */
const char *name; /* descriptive, user facing name of the mode */
+ bool isuser; /* whether this is a user or internal mode */
bool common_prefix; /* whether the first key in this mode is always the same */
void (*enter)(Mode *old); /* called right before the mode becomes active */
void (*leave)(Mode *new); /* called right before the mode becomes inactive */
@@ -146,7 +147,8 @@ typedef struct { /* command definitions for the ':'-prom
static volatile bool running = true; /* exit main loop once this becomes false */
static Editor *vis; /* global editor instance, keeps track of all windows etc. */
static Mode *mode; /* currently active mode, used to search for keybindings */
-static Mode *mode_prev; /* mode which was active previously */
+static Mode *mode_prev; /* previsouly active user mode */
+static Mode *mode_before_prompt; /* user mode which was active before entering prompt */
static Action action; /* current action which is in progress */
static Action action_prev; /* last operator action used by the repeat '.' key */
@@ -944,8 +946,9 @@ static void prompt_enter(const Arg *arg) {
* focused editor window *before* anything is executed which depends
* on vis->win.
*/
- switchmode_to(mode_prev);
- exec_command(vis->prompt->title[0], s);
+ switchmode_to(mode_before_prompt);
+ if (s && *s && exec_command(vis->prompt->title[0], s) && running)
+ switchmode(&(const Arg){ .i = VIS_MODE_NORMAL });
free(s);
editor_draw(vis);
}
@@ -1193,7 +1196,7 @@ static void switchmode_to(Mode *new_mode) {
return;
if (mode->leave)
mode->leave(new_mode);
- if (mode == config->mode || (mode->name && mode->name[0] == '-'))
+ if (mode->isuser)
mode_prev = mode;
mode = new_mode;
if (mode == config->mode || (mode->name && mode->name[0] == '-'))
diff --git a/window.c b/window.c
index 10f2ef4..be0ce0f 100644
--- a/window.c
+++ b/window.c
@@ -843,6 +843,8 @@ void window_scroll_to(Win *win, size_t pos) {
}
void window_selection_start(Win *win) {
+ if (win->sel.start != EPOS && win->sel.end != EPOS)
+ return;
win->sel.start = win->sel.end = window_cursor_get(win);
window_draw(win);
curs_set(0);