diff options
| author | Marc André Tanner <mat@brain-dump.org> | 2016-12-20 22:07:50 +0100 |
|---|---|---|
| committer | Marc André Tanner <mat@brain-dump.org> | 2016-12-20 22:08:42 +0100 |
| commit | 6aeb589a8acb296b15473811f6633644786c8b61 (patch) | |
| tree | fb8f956756268e0b7ad067348217094684dca4cf | |
| parent | b4b2c80752f32c0cbf72727a684dfbb2094179b1 (diff) | |
| download | vis-6aeb589a8acb296b15473811f6633644786c8b61.tar.gz vis-6aeb589a8acb296b15473811f6633644786c8b61.tar.xz | |
vis: improve literal insertion via <C-v> in insert mode
| -rw-r--r-- | main.c | 27 | ||||
| -rw-r--r-- | vis.c | 42 | ||||
| -rw-r--r-- | vis.h | 2 |
3 files changed, 50 insertions, 21 deletions
@@ -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[] = { - "<Enter>", "\n", - "<Tab>", "\t", - "<Backspace>", "\b", - "<Escape>", "\x1b", - "<DEL>", "\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) @@ -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; @@ -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 <Enter> 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. |
