aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--editor.c9
-rw-r--r--editor.h3
-rw-r--r--vis.c33
3 files changed, 44 insertions, 1 deletions
diff --git a/editor.c b/editor.c
index c07eed7..4484b0a 100644
--- a/editor.c
+++ b/editor.c
@@ -252,6 +252,14 @@ bool editor_mode_unmap(Mode *mode, const char *name) {
return map_delete(mode->bindings, name);
}
+bool editor_action_register(Editor *ed, KeyAction *action) {
+ if (!ed->actions)
+ ed->actions = map_new();
+ if (!ed->actions)
+ return false;
+ return map_put(ed->actions, action->name, action);
+}
+
static void window_free(Win *win) {
if (!win)
return;
@@ -430,6 +438,7 @@ void editor_free(Editor *ed) {
ed->ui->free(ed->ui);
map_free(ed->cmds);
map_free(ed->options);
+ map_free(ed->actions);
buffer_release(&ed->buffer_repeat);
free(ed);
}
diff --git a/editor.h b/editor.h
index 87d9aeb..e7b5f0a 100644
--- a/editor.h
+++ b/editor.h
@@ -253,6 +253,7 @@ struct Editor {
volatile sig_atomic_t cancel_filter; /* abort external command */
volatile sig_atomic_t sigbus;
sigjmp_buf sigbus_jmpbuf;
+ Map *actions; /* built in special editor keys / commands */
};
Editor *editor_new(Ui*);
@@ -266,6 +267,8 @@ bool editor_mode_bindings(Mode*, KeyBinding**);
bool editor_mode_map(Mode*, const char *name, KeyBinding*);
bool editor_mode_unmap(Mode*, const char *name);
+bool editor_action_register(Editor*, KeyAction*);
+
/* these function operate on the currently focused window but make sure
* that all windows which show the affected region are redrawn too. */
void editor_insert_key(Editor*, const char *data, size_t len);
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++) {