From e0b157f56694a5b5e535083c8fc0bc0e1194c9dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Andr=C3=A9=20Tanner?= Date: Fri, 12 Feb 2016 20:05:05 +0100 Subject: [PATCH] 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 behaviour in prompt for replace and visual line modes. --- vis-core.h | 1 + vis-modes.c | 6 ++++++ vis.c | 26 ++++++++++---------------- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/vis-core.h b/vis-core.h index 5939115d5..dab22a0bc 100644 --- a/vis-core.h +++ b/vis-core.h @@ -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 858e427c0..f519b5bd0 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--", diff --git a/vis.c b/vis.c index 489957a2d..1138dd7a8 100644 --- a/vis.c +++ b/vis.c @@ -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;