vis
a vi-like editor based on Plan 9's structural regular expressions
git clone https://9o.is/git/vis.git
commit 34955baa421d5dfc7c75e675693d2d352622bd28 parent 62ad464e2c5abc71586023fde75eca9a1ef135bf Author: Marc André Tanner <mat@brain-dump.org> Date: Sat, 13 Feb 2016 11:18:33 +0100 vis: add insfrastructure to support global key mappings Except for insert/replace mode keys get translated before any key bindings are evaluated. This is useful for non-english/latin keyboard layouts. Diffstat:
| M | config.def.h | | | 4 | ++++ |
| M | main.c | | | 3 | +++ |
| M | vis-core.h | | | 1 | + |
| M | vis.c | | | 12 | ++++++++++++ |
| M | vis.h | | | 3 | +++ |
5 files changed, 23 insertions(+), 0 deletions(-)
diff --git a/config.def.h b/config.def.h @@ -3,6 +3,10 @@ #define ALIAS(name) .alias = name, #define ACTION(id) .action = &vis_action[VIS_ACTION_##id], +static const char *keymaps[] = { + NULL +}; + static const KeyBinding bindings_basic[] = { { "<C-z>", ACTION(EDITOR_SUSPEND) }, { "<Left>", ACTION(CURSOR_CHAR_PREV) }, diff --git a/main.c b/main.c @@ -1830,6 +1830,9 @@ int main(int argc, char *argv[]) { } } + for (const char **k = keymaps; k[0]; k += 2) + vis_keymap_add(vis, k[0], k[1]); + /* install signal handlers etc. */ struct sigaction sa; memset(&sa, 0, sizeof sa); diff --git a/vis-core.h b/vis-core.h @@ -150,6 +150,7 @@ struct Vis { bool autoindent; /* whether indentation should be copied from previous line on newline */ Map *cmds; /* ":"-commands, used for unique prefix queries */ Map *options; /* ":set"-options */ + Map *keymap; /* key translation before any bindings are matched */ Buffer input_queue; /* holds pending input keys */ Buffer *keys; /* currently active keys buffer (either the input_queue or a macro) */ Action action; /* current action which is in progress */ diff --git a/vis.c b/vis.c @@ -341,6 +341,8 @@ Vis *vis_new(Ui *ui, VisEvent *event) { goto err; if (!(vis->search_file = file_new_internal(vis, NULL))) goto err; + if (!(vis->keymap = map_new())) + goto err; vis->mode_prev = vis->mode = &vis_modes[VIS_MODE_NORMAL]; vis->event = event; if (event && event->vis_start) @@ -371,6 +373,7 @@ void vis_free(Vis *vis) { map_free(vis->cmds); map_free(vis->options); map_free(vis->actions); + map_free(vis->keymap); buffer_release(&vis->input_queue); for (int i = 0; i < VIS_MODE_INVALID; i++) map_free(vis_modes[i].bindings); @@ -422,6 +425,10 @@ bool vis_action_register(Vis *vis, const KeyAction *action) { return map_put(vis->actions, action->name, action); } +bool vis_keymap_add(Vis *vis, const char *key, const char *mapping) { + return map_put(vis->keymap, key, mapping); +} + static void window_jumplist_add(Win *win, size_t pos) { Mark mark = text_mark_set(win->file->text, pos); if (mark && win->jumplist) @@ -763,6 +770,11 @@ static const char *getkey(Vis *vis) { if (!key) return NULL; vis_info_hide(vis); + if (!vis->mode->input) { + const char *mapped = map_get(vis->keymap, key); + if (mapped) + return mapped; + } return key; } diff --git a/vis.h b/vis.h @@ -138,6 +138,9 @@ const char *vis_mode_status(Vis*); /* associates the special pseudo key <keyaction->name> with the given key action. * after successfull registration the pseudo key can be used key binding aliases */ bool vis_action_register(Vis*, const KeyAction*); +/* add a key mapping which is applied for all modes except insert/replace + * before any key bindings are evaluated */ +bool vis_keymap_add(Vis*, const char *key, const char *mapping); enum VisOperator { VIS_OP_DELETE,