From 6aeb589a8acb296b15473811f6633644786c8b61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Andr=C3=A9=20Tanner?= Date: Tue, 20 Dec 2016 22:07:50 +0100 Subject: vis: improve literal insertion via in insert mode --- main.c | 27 ++++++--------------------- vis.c | 42 ++++++++++++++++++++++++++++++++++++++++++ vis.h | 2 ++ 3 files changed, 50 insertions(+), 21 deletions(-) diff --git a/main.c b/main.c index fdfe0bc..64f1132 100644 --- a/main.c +++ b/main.c @@ -1879,28 +1879,13 @@ static const char *insert_verbatim(Vis *vis, const char *keys, const Arg *arg) { const char *next = vis_keys_next(vis, keys); if (!next) return NULL; - size_t keylen = next - keys; - char key[keylen+1]; - memcpy(key, keys, keylen); - key[keylen] = '\0'; - - static const char *keysym[] = { - "", "\n", - "", "\t", - "", "\b", - "", "\x1b", - "", "\x7f", - NULL, - }; - - for (const char **k = keysym; k[0]; k += 2) { - if (strcmp(k[0], key) == 0) { - data = k[1]; - len = strlen(data); - keys = next; - break; - } + if ((rune = vis_keys_codepoint(vis, keys)) != (Rune)-1) { + len = runetochar(buf, &rune); + data = buf; + } else { + vis_info_show(vis, "Unknown key"); } + keys = next; } if (len > 0) diff --git a/vis.c b/vis.c index 55c55ce..302497f 100644 --- a/vis.c +++ b/vis.c @@ -865,6 +865,48 @@ const char *vis_keys_next(Vis *vis, const char *keys) { return keys; } +long vis_keys_codepoint(Vis *vis, const char *keys) { + long codepoint = -1; + const char *next; + TermKeyKey key; + TermKey *termkey = vis->ui->termkey_get(vis->ui); + + if (!keys[0]) + return -1; + if (keys[0] == '<' && !keys[1]) + return '<'; + + if (keys[0] == '<' && (next = termkey_strpkey(termkey, keys+1, &key, TERMKEY_FORMAT_VIM)) && *next == '>') + codepoint = (key.type == TERMKEY_TYPE_UNICODE) ? key.code.codepoint : -1; + else if ((next = termkey_strpkey(termkey, keys, &key, TERMKEY_FORMAT_VIM))) + codepoint = (key.type == TERMKEY_TYPE_UNICODE) ? key.code.codepoint : -1; + + if (codepoint != -1) { + if (key.modifiers == TERMKEY_KEYMOD_CTRL) + codepoint &= 0x1f; + return codepoint; + } + + if (!next || key.type != TERMKEY_TYPE_KEYSYM) + return -1; + + const int keysym[] = { + TERMKEY_SYM_ENTER, '\n', + TERMKEY_SYM_TAB, '\t', + TERMKEY_SYM_BACKSPACE, '\b', + TERMKEY_SYM_ESCAPE, 0x1b, + TERMKEY_SYM_DELETE, 0x7f, + 0, + }; + + for (const int *k = keysym; k[0]; k += 2) { + if (key.code.sym == k[0]) + return k[1]; + } + + return -1; +} + static void vis_keys_process(Vis *vis, size_t pos) { Buffer *buf = vis->keys; char *keys = buf->data + pos, *start = keys, *cur = keys, *end = keys; diff --git a/vis.h b/vis.h index 74794b6..69bef3b 100644 --- a/vis.h +++ b/vis.h @@ -473,6 +473,8 @@ int vis_pipe_collect(Vis *vis, Filerange *range, const char *argv[], char **out, * following as will be processed by the input system. skips over special keys * such as as well as pseudo keys registered via vis_action_register. */ const char *vis_keys_next(Vis*, const char *keys); +/* Tries to convert next symbolic key to a raw code point, returns -1 for unknown keys */ +long vis_keys_codepoint(Vis*, const char *keys); /* vis operates as a finite state machine (FSM), feeding keys from an input * queue (or a previously recorded macro) to key handling functions (see struct * KeyAction) which consume the input. -- cgit v1.2.3