aboutsummaryrefslogtreecommitdiff
path: root/vis.c
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2015-10-14 23:00:47 +0200
committerMarc André Tanner <mat@brain-dump.org>2015-10-14 23:17:15 +0200
commit632b5909af96861c881865afae8638a2fd072668 (patch)
tree22c745db9a95d6a8c999f0026a3d2e2301d95100 /vis.c
parentfc8b564ab2a58cf5dd19dcaabd460b65bd5d444c (diff)
downloadvis-632b5909af96861c881865afae8638a2fd072668.tar.gz
vis-632b5909af96861c881865afae8638a2fd072668.tar.xz
vis: introduce special keys which allow mappings to editor actions
Key bindings in vis are always recursive, hence mapping ~ to ~l will cause an infinite loop. Instead vis supports special editor "keys" which map to internal editor functions. As an example one can thus map ~ to <vis-operator-case-swap>l or even <vis-operator-case-swap><cursor-char-next> Furthermore this makes it possible to completely unmap core editor features such as operators, the corresponding funtionality is still available via its corresponding special key.
Diffstat (limited to 'vis.c')
-rw-r--r--vis.c33
1 files changed, 32 insertions, 1 deletions
diff --git a/vis.c b/vis.c
index 5057ab9..c4fbc29 100644
--- a/vis.c
+++ b/vis.c
@@ -2600,6 +2600,18 @@ static const char *keynext(const char *keys) {
/* first try to parse a special key of the form <Key> */
if (*keys == '<' && (next = termkey_strpkey(termkey, keys+1, &key, TERMKEY_FORMAT_VIM)) && *next == '>')
return next+1;
+ if (*keys == '<') {
+ const char *start = keys + 1, *end = start;
+ while (*end && *end != '>')
+ end++;
+ if (end > start && end - start - 1 < 64 && *end == '>') {
+ char key[64];
+ memcpy(key, start, end - start);
+ key[end - start] = '\0';
+ if (map_get(vis->actions, key))
+ return end + 1;
+ }
+ }
while (!ISUTF8(*keys))
keys++;
return termkey_strpkey(termkey, keys, &key, TERMKEY_FORMAT_VIM);
@@ -2655,7 +2667,20 @@ static const char *keypress(const char *input) {
} else if (prefix) { /* incomplete key binding? */
cur = end;
} else { /* no keybinding */
- if (vis->mode->input)
+ KeyAction *action = NULL;
+ if (start[0] == '<' && end[-1] == '>') {
+ /* test for special editor key command */
+ char tmp = end[-1];
+ end[-1] = '\0';
+ action = map_get(vis->actions, start+1);
+ end[-1] = tmp;
+ if (action) {
+ end = (char*)action->func(end, &action->arg);
+ if (!end)
+ break;
+ }
+ }
+ if (!action && vis->mode->input)
vis->mode->input(start, end - start);
start = cur = end;
}
@@ -2780,6 +2805,12 @@ int main(int argc, char *argv[]) {
if (!editor_syntax_load(vis, syntaxes))
die("Could not load syntax highlighting definitions\n");
+ for (int i = 0; i < LENGTH(vis_action); i++) {
+ KeyAction *action = &vis_action[i];
+ if (!editor_action_register(vis, action))
+ die("Could not register action: %s\n", action->name);
+ }
+
char *cmd = NULL;
bool end_of_options = false;
for (int i = 1; i < argc; i++) {