diff options
| author | Marc André Tanner <mat@brain-dump.org> | 2016-05-13 23:13:52 +0200 |
|---|---|---|
| committer | Marc André Tanner <mat@brain-dump.org> | 2016-05-13 23:13:52 +0200 |
| commit | a1881512f3050e8d6719a28b55846c1f4c93acab (patch) | |
| tree | dc825eecd6bff16a2ca4b76cf48c8f0a5c0090d3 | |
| parent | 9a9f7a96f5b02777b8c0823cffd173a72ca3e3c2 (diff) | |
| download | vis-a1881512f3050e8d6719a28b55846c1f4c93acab.tar.gz vis-a1881512f3050e8d6719a28b55846c1f4c93acab.tar.xz | |
vis: clean up key mapping implementation
| -rw-r--r-- | main.c | 2 | ||||
| -rw-r--r-- | vis-cmds.c | 25 | ||||
| -rw-r--r-- | vis-lua.c | 16 | ||||
| -rw-r--r-- | vis-modes.c | 54 | ||||
| -rw-r--r-- | vis-prompt.c | 12 | ||||
| -rw-r--r-- | vis.h | 9 |
6 files changed, 51 insertions, 67 deletions
@@ -2125,7 +2125,7 @@ int main(int argc, char *argv[]) { for (int i = 0; i < LENGTH(default_bindings); i++) { for (const KeyBinding **binding = default_bindings[i]; binding && *binding; binding++) { for (const KeyBinding *kb = *binding; kb->key; kb++) { - vis_mode_map(vis, i, kb->key, kb); + vis_mode_map(vis, i, false, kb->key, kb); } } } @@ -755,36 +755,19 @@ static bool cmd_map(Vis *vis, Win *win, Command *cmd, const char *argv[], Cursor return false; } - char *lhs = strdup(argv[2]); + const char *lhs = argv[2]; char *rhs = strdup(argv[3]); - if (!lhs || !rhs || !(binding = calloc(1, sizeof *binding))) + if (!rhs || !(binding = calloc(1, sizeof *binding))) goto err; - char *next = lhs; - while (cmd->flags == '!' && next) { - char tmp; - next = (char*)vis_keys_next(vis, next); - if (next) { - tmp = *next; - *next = '\0'; - } - if (local) - vis_window_mode_unmap(win, mode, lhs); - else - vis_mode_unmap(vis, mode, lhs); - if (next) - *next = tmp; - } - binding->alias = rhs; if (local) - mapped = vis_window_mode_map(win, mode, lhs, binding); + mapped = vis_window_mode_map(win, mode, cmd->flags == '!', lhs, binding); else - mapped = vis_mode_map(vis, mode, lhs, binding); + mapped = vis_mode_map(vis, mode, cmd->flags == '!', lhs, binding); err: - free(lhs); if (!mapped) { free(rhs); free(binding); @@ -410,21 +410,7 @@ static int map(lua_State *L) { binding->action = action; - char *lhs = strdup(key), *next = lhs; - while (next) { - char tmp; - next = (char*)vis_keys_next(vis, next); - if (next) { - tmp = *next; - *next = '\0'; - } - vis_mode_unmap(vis, mode, lhs); - if (next) - *next = tmp; - } - free(lhs); - - if (!vis_mode_map(vis, mode, key, binding)) + if (!vis_mode_map(vis, mode, true, key, binding)) goto err; lua_pushboolean(L, true); diff --git a/vis-modes.c b/vis-modes.c index 62a9541..ad866f7 100644 --- a/vis-modes.c +++ b/vis-modes.c @@ -25,37 +25,51 @@ void vis_mode_switch(Vis *vis, enum VisMode mode) { mode_set(vis, &vis_modes[mode]); } -static bool mode_map(Mode *mode, const char *key, const KeyBinding *binding) { +static bool mode_unmap(Mode *mode, const char *key) { + return mode && mode->bindings && map_delete(mode->bindings, key); +} + +bool vis_mode_unmap(Vis *vis, enum VisMode id, const char *key) { + return id < LENGTH(vis_modes) && mode_unmap(&vis_modes[id], key); +} + +bool vis_window_mode_unmap(Win *win, enum VisMode id, const char *key) { + return id < LENGTH(win->modes) && mode_unmap(&win->modes[id], key); +} + +static bool mode_map(Vis *vis, Mode *mode, bool force, const char *key, const KeyBinding *binding) { if (!mode) return false; if (binding->alias && key[0] != '<' && strncmp(key, binding->alias, strlen(key)) == 0) return false; - if (!mode->bindings) { - mode->bindings = map_new(); - if (!mode->bindings) + if (!mode->bindings && !(mode->bindings = map_new())) + return false; + if (force) { + char *lhs = strdup(key), *next = lhs; + if (!lhs) return false; + while (next) { + char tmp; + next = (char*)vis_keys_next(vis, next); + if (next) { + tmp = *next; + *next = '\0'; + } + mode_unmap(mode, lhs); + if (next) + *next = tmp; + } + free(lhs); } return (strcmp(key, "<") == 0 || !map_contains(mode->bindings, key)) && map_put(mode->bindings, key, binding); } -bool vis_mode_map(Vis *vis, enum VisMode id, const char *key, const KeyBinding *binding) { - return id < LENGTH(vis_modes) && mode_map(&vis_modes[id], key, binding); +bool vis_mode_map(Vis *vis, enum VisMode id, bool force, const char *key, const KeyBinding *binding) { + return id < LENGTH(vis_modes) && mode_map(vis, &vis_modes[id], force, key, binding); } -bool vis_window_mode_map(Win *win, enum VisMode id, const char *key, const KeyBinding *binding) { - return id < LENGTH(win->modes) && mode_map(&win->modes[id], key, binding); -} - -static bool mode_unmap(Mode *mode, const char *key) { - return mode && mode->bindings && map_delete(mode->bindings, key); -} - -bool vis_mode_unmap(Vis *vis, enum VisMode id, const char *key) { - return id < LENGTH(vis_modes) && mode_unmap(&vis_modes[id], key); -} - -bool vis_window_mode_unmap(Win *win, enum VisMode id, const char *key) { - return id < LENGTH(win->modes) && mode_unmap(&win->modes[id], key); +bool vis_window_mode_map(Win *win, enum VisMode id, bool force, const char *key, const KeyBinding *binding) { + return id < LENGTH(win->modes) && mode_map(win->vis, &win->modes[id], force, key, binding); } /** mode switching event handlers */ diff --git a/vis-prompt.c b/vis-prompt.c index 01dc916..8f7e1a9 100644 --- a/vis-prompt.c +++ b/vis-prompt.c @@ -165,12 +165,12 @@ void vis_prompt_show(Vis *vis, const char *title) { view_draw(prompt->view); prompt->parent = active; prompt->parent_mode = vis->mode; - vis_window_mode_map(prompt, VIS_MODE_NORMAL, "<Enter>", &prompt_enter_binding); - vis_window_mode_map(prompt, VIS_MODE_INSERT, "<Enter>", &prompt_enter_binding); - vis_window_mode_map(prompt, VIS_MODE_VISUAL, "<Enter>", &prompt_enter_binding); - vis_window_mode_map(prompt, VIS_MODE_NORMAL, "<Escape>", &prompt_esc_binding); - vis_window_mode_map(prompt, VIS_MODE_INSERT, "<Up>", &prompt_up_binding); - vis_window_mode_map(prompt, VIS_MODE_INSERT, "<Backspace>", &prompt_backspace_binding); + vis_window_mode_map(prompt, VIS_MODE_NORMAL, true, "<Enter>", &prompt_enter_binding); + vis_window_mode_map(prompt, VIS_MODE_INSERT, true, "<Enter>", &prompt_enter_binding); + vis_window_mode_map(prompt, VIS_MODE_VISUAL, true, "<Enter>", &prompt_enter_binding); + vis_window_mode_map(prompt, VIS_MODE_NORMAL, true, "<Escape>", &prompt_esc_binding); + vis_window_mode_map(prompt, VIS_MODE_INSERT, true, "<Up>", &prompt_up_binding); + vis_window_mode_map(prompt, VIS_MODE_INSERT, true, "<Backspace>", &prompt_backspace_binding); vis_mode_switch(vis, VIS_MODE_INSERT); vis_draw(vis); } @@ -132,10 +132,11 @@ enum VisMode { }; void vis_mode_switch(Vis*, enum VisMode); -/* in the specified mode: map a given key to a binding (binding->key is ignored), - * fails if key is already mapped */ -bool vis_mode_map(Vis*, enum VisMode, const char *key, const KeyBinding*); -bool vis_window_mode_map(Win*, enum VisMode, const char *key, const KeyBinding*); +/* In the specified mode: map a given key to a binding (binding->key is ignored). + * Fails if a prefix of `key' is already mapped and `force' is false. Otherwise + * all such prefixes are unmapped. */ +bool vis_mode_map(Vis*, enum VisMode, bool force, const char *key, const KeyBinding*); +bool vis_window_mode_map(Win*, enum VisMode, bool force, const char *key, const KeyBinding*); /* in the specified mode: unmap a given key, fails if the key is not currently mapped */ bool vis_mode_unmap(Vis*, enum VisMode, const char *key); bool vis_window_mode_unmap(Win*, enum VisMode, const char *key); |
