aboutsummaryrefslogtreecommitdiff
path: root/vis.c
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2016-08-20 16:01:43 +0200
committerMarc André Tanner <mat@brain-dump.org>2016-08-24 11:10:00 +0200
commitc0e86f811b3a8e4f45768db86e97d1b0fda5616f (patch)
tree0dfc6da2764d6999256338e86180765b53abc633 /vis.c
parentc7df560b818224d9a9ca3b0ba31a54312dc7062b (diff)
downloadvis-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.
Diffstat (limited to 'vis.c')
-rw-r--r--vis.c66
1 files changed, 27 insertions, 39 deletions
diff --git a/vis.c b/vis.c
index ff212cc..f6b28f1 100644
--- a/vis.c
+++ b/vis.c
@@ -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) {