aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2016-02-13 11:18:33 +0100
committerMarc André Tanner <mat@brain-dump.org>2016-02-18 16:22:20 +0100
commitb2e2b449d26a794f10929a2861df4c1b33af7966 (patch)
tree81ecce2e25d000197e1bffa974f67fdbbeedca2a
parentefc9b14dcee610a494401abf483126c8d6dd9e0a (diff)
downloadvis-b2e2b449d26a794f10929a2861df4c1b33af7966.tar.gz
vis-b2e2b449d26a794f10929a2861df4c1b33af7966.tar.xz
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.
-rw-r--r--config.def.h4
-rw-r--r--main.c3
-rw-r--r--vis-core.h1
-rw-r--r--vis.c12
-rw-r--r--vis.h3
5 files changed, 23 insertions, 0 deletions
diff --git a/config.def.h b/config.def.h
index b7a797e..4902415 100644
--- 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
index 2f49bff..fb77b67 100644
--- 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
index dab22a0..a201828 100644
--- 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
index 848180f..35516de 100644
--- 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
index 2d3fcdd..dc087f9 100644
--- 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,