From 38f00e3e8a50e1690dcb78cf1eca8b6befb7173b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Andr=C3=A9=20Tanner?= Date: Sat, 18 Jul 2015 10:35:32 +0200 Subject: vis: improve insertion of verbatim characters via CTRL-V in insert mode Recognized formats are: CTRL-V nnn decimal value nnn CTRL-V onnn or CTRL-V Onnn octal value nnn CTRL-V xnn or CTRL-V Xnn hex value nn CTRL-V unnnn Unicode codepoint nnnn CTRL-V Unnnnnnnn Unicode codepoint nnnnnnnn Leading zeros can be omitted, any illegal character for the given format will be ignored and terminates the numerical code. --- vis.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 58 insertions(+), 7 deletions(-) (limited to 'vis.c') diff --git a/vis.c b/vis.c index ffe45ce..339bfb0 100644 --- a/vis.c +++ b/vis.c @@ -39,6 +39,7 @@ #include "text-objects.h" #include "util.h" #include "map.h" +#include "libutf.h" /** global variables */ static Editor *vis; /* global editor instance, keeps track of all windows etc. */ @@ -1037,15 +1038,65 @@ static void prompt_backspace(const Arg *arg) { } static void insert_verbatim(const Arg *arg) { - int value = 0; - for (int i = 0; i < 3; i++) { - Key k = getkey(); - if (k.str[0] < '0' || k.str[0] > '9') + int len = 0, count = 0, base; + Rune rune = 0; + Key key = getkey(); + char buf[4], type = key.str[0]; + switch (type) { + case 'o': + case 'O': + count = 3; + base = 8; + break; + case 'U': + count = 4; + /* fall through */ + case 'u': + count += 4; + base = 16; + break; + case 'x': + case 'X': + count = 2; + base = 16; + break; + default: + if (type < '0' || type > '9') return; - value = value * 10 + k.str[0] - '0'; + rune = type - '0'; + count = 2; + base = 10; + break; + } + + while (count-- > 0) { + key = getkey(); + int v = 0; + if (base == 8 && '0' <= key.str[0] && key.str[0] <= '7') + v = key.str[0] - '0'; + else if ((base == 10 || base == 16) && '0' <= key.str[0] && key.str[0] <= '9') + v = key.str[0] - '0'; + else if (base == 16 && 'a' <= key.str[0] && key.str[0] <= 'f') + v = 10 + key.str[0] - 'a'; + else if (base == 16 && 'A' <= key.str[0] && key.str[0] <= 'F') + v = 10 + key.str[0] - 'A'; + else + break; + rune = rune * base + v; + } + + if (type == 'u' || type == 'U') { + len = runetochar(buf, &rune); + } else { + buf[0] = rune; + len = 1; + } + + if (len > 0) { + size_t pos = view_cursor_get(vis->win->view); + editor_insert(vis, pos, buf, len); + view_cursor_to(vis->win->view, pos + len); } - char v = value; - editor_insert(vis, view_cursor_get(vis->win->view), &v, 1); } static void quit(const Arg *arg) { -- cgit v1.2.3