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;