vis

a vi-like editor based on Plan 9's structural regular expressions

git clone https://9o.is/git/vis.git

commit 1b8adfd3e01ea064d2af327f4e734036151cffd6
parent 1697a3f333c60552c3d4a3fff103b28c03ae39a9
Author: Marc André Tanner <mat@brain-dump.org>
Date:   Tue,  3 Nov 2015 16:28:52 +0100

vis: add vis_keys_inject to place keys into the input queue

This function can only be used from within key handlers.

The position argument has to point to a valid key from
within the same input buffer after which the new input
will be inserted.

Diffstat:
Mvis.c | 30++++++++++++++++++++++++------
Mvis.h | 1+
2 files changed, 25 insertions(+), 6 deletions(-)

diff --git a/vis.c b/vis.c @@ -188,6 +188,8 @@ struct Vis { volatile sig_atomic_t sigbus; sigjmp_buf sigbus_jmpbuf; Map *actions; /* built in special editor keys / commands */ + Buffer *keys; /* if non-NULL we are currently handling keys from this buffer, + * points to either the input_queue or a macro */ }; /* TODO make part of struct Vis? */ @@ -2676,11 +2678,8 @@ static const char *vis_keys_raw(Vis *vis, Buffer *buf, const char *input) { while (cur && *cur) { - if (!(end = (char*)vis_key_next(vis, cur))) { - // XXX: can't parse key this should never happen, throw away remaining input - buffer_truncate(buf); - return input + strlen(input); - } + if (!(end = (char*)vis_key_next(vis, cur))) + goto err; // XXX: can't parse key this should never happen char tmp = *end; *end = '\0'; @@ -2696,7 +2695,8 @@ static const char *vis_keys_raw(Vis *vis, Buffer *buf, const char *input) { } *end = tmp; - + vis->keys = buf; + if (binding) { /* exact match */ if (binding->action) { end = (char*)binding->action->func(vis, end, &binding->action->arg); @@ -2730,8 +2730,26 @@ static const char *vis_keys_raw(Vis *vis, Buffer *buf, const char *input) { } } + vis->keys = NULL; buffer_put0(buf, start); return input + (start - keys); +err: + vis->keys = NULL; + buffer_truncate(buf); + return input + strlen(input); +} + +bool vis_keys_inject(Vis *vis, const char *pos, const char *input) { + Buffer *buf = vis->keys; + if (!buf) + return false; + if (pos < buf->data || pos > buf->data + buf->len) + return false; + size_t off = pos - buf->data; + buffer_insert0(buf, off, input); + if (vis->macro_operator) + macro_append(vis->macro_operator, input); + return true; } const char *vis_keys(Vis *vis, const char *input) { diff --git a/vis.h b/vis.h @@ -323,6 +323,7 @@ bool vis_cmd(Vis*, const char *cmd); const char *vis_key_next(Vis*, const char *keys); const char *vis_keys(Vis*, const char *input); +bool vis_keys_inject(Vis*, const char *pos, const char *input); bool vis_signal_handler(Vis*, int signum, const siginfo_t *siginfo, const void *context);