aboutsummaryrefslogtreecommitdiff
path: root/vis.c
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2015-07-18 10:35:32 +0200
committerMarc André Tanner <mat@brain-dump.org>2015-07-20 12:05:45 +0200
commit38f00e3e8a50e1690dcb78cf1eca8b6befb7173b (patch)
treef613eec7ee39a312229e97d22557623ef7a2510f /vis.c
parent0fa9885cda0778467ca5737ac888ece5ef371b3d (diff)
downloadvis-38f00e3e8a50e1690dcb78cf1eca8b6befb7173b.tar.gz
vis-38f00e3e8a50e1690dcb78cf1eca8b6befb7173b.tar.xz
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.
Diffstat (limited to 'vis.c')
-rw-r--r--vis.c65
1 files changed, 58 insertions, 7 deletions
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) {