aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2016-12-20 22:07:50 +0100
committerMarc André Tanner <mat@brain-dump.org>2016-12-20 22:08:42 +0100
commit6aeb589a8acb296b15473811f6633644786c8b61 (patch)
treefb8f956756268e0b7ad067348217094684dca4cf
parentb4b2c80752f32c0cbf72727a684dfbb2094179b1 (diff)
downloadvis-6aeb589a8acb296b15473811f6633644786c8b61.tar.gz
vis-6aeb589a8acb296b15473811f6633644786c8b61.tar.xz
vis: improve literal insertion via <C-v> in insert mode
-rw-r--r--main.c27
-rw-r--r--vis.c42
-rw-r--r--vis.h2
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[] = {
- "<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)
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 <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.