vis

a vi-like editor based on Plan 9's structural regular expressions

git clone https://9o.is/git/vis.git

commit 8a5acf12125f5f1584fada7cc9125e16fb92da43
parent f1d01cb8b6f7bcfccdd9b49fe9251761430a7cdd
Author: Marc André Tanner <mat@brain-dump.org>
Date:   Fri, 12 Feb 2016 20:05:05 +0100

vis: respect window local mappings for child modes

Since commit cb0611c25571e6cab88f054c4add4868075f34b7 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.

Diffstat:
Mvis-core.h | 1+
Mvis-modes.c | 6++++++
Mvis.c | 26++++++++++----------------
3 files changed, 17 insertions(+), 16 deletions(-)

diff --git 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 @@ -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 @@ -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;