diff options
| author | Marc André Tanner <mat@brain-dump.org> | 2016-02-12 20:05:05 +0100 |
|---|---|---|
| committer | Marc André Tanner <mat@brain-dump.org> | 2016-02-12 20:05:05 +0100 |
| commit | e0b157f56694a5b5e535083c8fc0bc0e1194c9dc (patch) | |
| tree | 2beb33ea2397ae4ad091a12642a4f772e67c23ac | |
| parent | 49fffba7d02d116bbfffb5244aa17df6c2cdcbd2 (diff) | |
| download | vis-e0b157f56694a5b5e535083c8fc0bc0e1194c9dc.tar.gz vis-e0b157f56694a5b5e535083c8fc0bc0e1194c9dc.tar.xz | |
vis: respect window local mappings for child modes
Since commit 197ab824206335eab7ceed774ddeccac18fafc09 visual line
and replace modes are child modes, hence we also have to consider
the window local key bindings of their respective parent modes.
For example in replace mode the key lookup chain is now as follows:
window local replace mode -> global replace mode ->
window local insert mode -> global insert mode
This fixes <Enter> behaviour in prompt for replace and visual line
modes.
| -rw-r--r-- | vis-core.h | 1 | ||||
| -rw-r--r-- | vis-modes.c | 6 | ||||
| -rw-r--r-- | vis.c | 26 |
3 files changed, 17 insertions, 16 deletions
@@ -21,6 +21,7 @@ */ typedef struct Mode Mode; struct Mode { + enum VisMode id; Mode *parent; /* if no match is found in this mode, search will continue there */ Map *bindings; const char *name; /* descriptive, user facing name of the mode */ diff --git a/vis-modes.c b/vis-modes.c index 858e427..f519b5b 100644 --- a/vis-modes.c +++ b/vis-modes.c @@ -140,16 +140,19 @@ static void vis_mode_replace_input(Vis *vis, const char *str, size_t len) { Mode vis_modes[] = { [VIS_MODE_OPERATOR_PENDING] = { + .id = VIS_MODE_OPERATOR_PENDING, .name = "OPERATOR-PENDING", .input = vis_mode_operator_input, .help = "", }, [VIS_MODE_NORMAL] = { + .id = VIS_MODE_NORMAL, .name = "NORMAL", .status = "", .help = "", }, [VIS_MODE_VISUAL] = { + .id = VIS_MODE_VISUAL, .name = "VISUAL", .status = "--VISUAL--", .help = "", @@ -158,6 +161,7 @@ Mode vis_modes[] = { .visual = true, }, [VIS_MODE_VISUAL_LINE] = { + .id = VIS_MODE_VISUAL_LINE, .name = "VISUAL LINE", .parent = &vis_modes[VIS_MODE_VISUAL], .status = "--VISUAL LINE--", @@ -167,6 +171,7 @@ Mode vis_modes[] = { .visual = true, }, [VIS_MODE_INSERT] = { + .id = VIS_MODE_INSERT, .name = "INSERT", .status = "--INSERT--", .help = "", @@ -177,6 +182,7 @@ Mode vis_modes[] = { .idle_timeout = 3, }, [VIS_MODE_REPLACE] = { + .id = VIS_MODE_REPLACE, .name = "REPLACE", .parent = &vis_modes[VIS_MODE_INSERT], .status = "--REPLACE--", @@ -670,25 +670,19 @@ static const char *vis_keys_raw(Vis *vis, Buffer *buf, const char *input) { prefix = false; binding = NULL; - Mode *mode = vis->mode; - for (size_t i = 0; i < LENGTH(vis->win->modes); i++) { - if (mode == &vis_modes[i]) { - if (vis->win->modes[i].bindings) - mode = &vis->win->modes[i]; - break; + for (Mode *mode = vis->mode; mode && !binding && !prefix; mode = mode->parent) { + for (int global = 0; global < 2 && !binding && !prefix; global++) { + Mode *mode_local = global ? mode : &vis->win->modes[mode->id]; + if (!mode_local->bindings) + continue; + binding = map_get(mode_local->bindings, start); + /* "<" is never treated as a prefix because it is used to denote + * special key symbols */ + if (strcmp(cur, "<")) + prefix = !binding && map_contains(mode_local->bindings, start); } } - for (; mode && !binding && !prefix; mode = mode->parent) { - if (!mode->bindings) - continue; - binding = map_get(mode->bindings, start); - /* "<" is never treated as a prefix because it is used to denote - * special key symbols */ - if (strcmp(cur, "<")) - prefix = !binding && map_contains(mode->bindings, start); - } - *end = tmp; vis->keys = buf; |
