diff options
| author | Marc André Tanner <mat@brain-dump.org> | 2016-08-20 16:01:43 +0200 |
|---|---|---|
| committer | Marc André Tanner <mat@brain-dump.org> | 2016-08-24 11:10:00 +0200 |
| commit | c0e86f811b3a8e4f45768db86e97d1b0fda5616f (patch) | |
| tree | 0dfc6da2764d6999256338e86180765b53abc633 | |
| parent | c7df560b818224d9a9ca3b0ba31a54312dc7062b (diff) | |
| download | vis-c0e86f811b3a8e4f45768db86e97d1b0fda5616f.tar.gz vis-c0e86f811b3a8e4f45768db86e97d1b0fda5616f.tar.xz | |
vis: overhaul input queue handling
Let vis_keys_feed always have an immediate effect. Previously,
if called from a key input handler the keys would just be added
to the input queue and processed once the current key handler
returned.
This also affects the exposed Lua API.
| -rw-r--r-- | README.md | 2 | ||||
| -rw-r--r-- | vis-core.h | 1 | ||||
| -rw-r--r-- | vis.c | 66 | ||||
| -rw-r--r-- | vis.h | 6 |
4 files changed, 30 insertions, 45 deletions
@@ -601,7 +601,7 @@ At this time there exists no API stability guarantees. - `motion(id)` select/execute a motion - `command_register(name, function(argv, force, win, cursor, range))` hook up a Lua function to `:name` command - `map(mode, key, function)` map a Lua function to `key` in `mode` - - `feedkeys(keys)` interpret `keys` as if they were read from the keyboard. If called from a key handling function, the keys will only be processed *after* the current key handling function has returned. + - `feedkeys(keys)` interpret `keys` as if they were read from the keyboard - `recording` boolean property, indicates whether a macro is currently being recorded - `file` - `content(pos, len)` or `content({start, finish})` @@ -163,7 +163,6 @@ struct Vis { 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) */ - bool keyhandler; /* whether a key handling function is currently being called */ bool errorhandler; /* whether we are currently in an error handler, used to avoid recursion */ Action action; /* current action which is in progress */ Action action_prev; /* last operator action used by the repeat (dot) command */ @@ -31,7 +31,7 @@ static Macro *macro_get(Vis *vis, enum VisRegister); static void macro_replay(Vis *vis, const Macro *macro); -static void vis_keys_process(Vis *vis); +static void vis_keys_push(Vis *vis, const char *input, size_t pos, bool record); /** window / file handling */ @@ -770,18 +770,17 @@ const char *vis_keys_next(Vis *vis, const char *keys) { return termkey_strpkey(termkey, keys, &key, TERMKEY_FORMAT_VIM); } -static void vis_keys_process(Vis *vis) { +static void vis_keys_process(Vis *vis, size_t pos) { Buffer *buf = vis->keys; - char *keys = buf->data, *start = keys, *cur = keys, *end; - bool prefix = false, unknown_key = false; + char *keys = buf->data + pos, *start = keys, *cur = keys, *end = keys; + bool prefix = false; KeyBinding *binding = NULL; - vis->keyhandler = true; while (cur && *cur) { if (!(end = (char*)vis_keys_next(vis, cur))) { - unknown_key = true; - goto out; + buffer_remove(buf, keys - buf->data, strlen(keys)); + return; } char tmp = *end; @@ -807,13 +806,15 @@ static void vis_keys_process(Vis *vis) { if (binding) { /* exact match */ if (binding->action) { end = (char*)binding->action->func(vis, end, &binding->action->arg); - if (!end) + if (!end) { + end = start; break; + } start = cur = end; } else if (binding->alias) { - buffer_put0(buf, end); - buffer_prepend0(buf, binding->alias); - start = cur = buf->data; + buffer_remove(buf, start - buf->data, end - start); + buffer_insert0(buf, start - buf->data, binding->alias); + cur = start; } } else if (prefix) { /* incomplete key binding? */ cur = end; @@ -827,8 +828,10 @@ static void vis_keys_process(Vis *vis) { end[-1] = tmp; if (action) { end = (char*)action->func(vis, end, &action->arg); - if (!end) + if (!end) { + end = start; break; + } } } if (!action && vis->mode->input) @@ -837,29 +840,23 @@ static void vis_keys_process(Vis *vis) { } } -out: - if (unknown_key) - buffer_truncate(buf); - else - buffer_put0(buf, start); - vis->keyhandler = false; + if (!prefix) + buffer_remove(buf, keys - buf->data, end - keys); } void vis_keys_feed(Vis *vis, const char *input) { + vis_keys_push(vis, input, buffer_length0(vis->keys), false); +} + +static void vis_keys_push(Vis *vis, const char *input, size_t pos, bool record) { if (!input) return; - if (vis->recording) + if (record && vis->recording) macro_append(vis->recording, input); if (vis->macro_operator) macro_append(vis->macro_operator, input); - if (!buffer_append0(vis->keys, input)) - buffer_truncate(vis->keys); - /* if we are being called from within a keyhandler then appending - * the new keys to the end of the input queue is enough. they will - * be interpreted once the key handler returns and control reaches - * back to the vis_keys_process function. */ - if (!vis->keyhandler) - vis_keys_process(vis); + if (buffer_append0(vis->keys, input)) + vis_keys_process(vis, pos); } static const char *getkey(Vis *vis) { @@ -1009,7 +1006,7 @@ int vis_run(Vis *vis, int argc, char *argv[]) { const char *key; while ((key = getkey(vis))) - vis_keys_feed(vis, key); + vis_keys_push(vis, key, 0, true); if (vis->mode->idle) timeout = &idle; @@ -1069,9 +1066,7 @@ bool vis_macro_recording(Vis *vis) { } static void macro_replay(Vis *vis, const Macro *macro) { - Buffer buf, *input_queue = vis->keys; - buffer_init(&buf); - vis->keys = &buf; + size_t pos = buffer_length0(vis->keys); for (char *key = macro->data, *next; key; key = next) { char tmp; next = (char*)vis_keys_next(vis, key); @@ -1080,18 +1075,11 @@ static void macro_replay(Vis *vis, const Macro *macro) { *next = '\0'; } - if (vis->macro_operator) - macro_append(vis->macro_operator, key); - if (!buffer_append0(&buf, key)) - buffer_truncate(&buf); - vis_keys_process(vis); + vis_keys_push(vis, key, pos, false); if (next) *next = tmp; } - - buffer_release(&buf); - vis->keys = input_queue; } bool vis_macro_replay(Vis *vis, enum VisRegister id) { @@ -458,10 +458,8 @@ const char *vis_keys_next(Vis*, const char *keys); * queue (or a previously recorded macro) to key handling functions (see struct * KeyAction) which consume the input. * - * this functions pushes/appends further input to the end of the input queue. - * if it is called from within a key handling function itself, the fed keys - * will be interpreted once the key handler returns. otherwhise the keys are - * immediately interpreted as if they were entered from a user. */ + * this functions pushes/appends further input to the end of the input queue + * and immediately interprets them as if they were entered by a user. */ void vis_keys_feed(Vis*, const char *keys); /* inform vis that a signal occured, the return value indicates whether the signal |
