diff options
Diffstat (limited to 'test/util')
| -rw-r--r-- | test/util/.gitignore | 1 | ||||
| -rw-r--r-- | test/util/Makefile | 11 | ||||
| -rw-r--r-- | test/util/README.md | 9 | ||||
| -rw-r--r-- | test/util/keys.c | 182 |
4 files changed, 203 insertions, 0 deletions
diff --git a/test/util/.gitignore b/test/util/.gitignore new file mode 100644 index 0000000..f8e3d19 --- /dev/null +++ b/test/util/.gitignore @@ -0,0 +1 @@ +/keys
\ No newline at end of file diff --git a/test/util/Makefile b/test/util/Makefile new file mode 100644 index 0000000..2c8161f --- /dev/null +++ b/test/util/Makefile @@ -0,0 +1,11 @@ +-include ../../config.mk + +keys: keys.c + @echo Compiling keys utility + $(CC) $(CFLAGS) $(CFLAGS_TERMKEY) keys.c $(LDFLAGS) $(LDFLAGS_TERMKEY) $(LDFLAGS_CURSES) -o keys + +clean: + @echo cleaning + @rm -f keys + +.PHONY: clean diff --git a/test/util/README.md b/test/util/README.md new file mode 100644 index 0000000..5f2369a --- /dev/null +++ b/test/util/README.md @@ -0,0 +1,9 @@ +Utility to turn symbolic keys into terminal input +------------------------------------------------- + +This is a small helper utility which translates symbolic keys, as provided +by [libtermkey](http://www.leonerd.org.uk/code/libtermkey/) and also used +to specify key bindings within vis, to their corresponding codes understood +by terminal programs. + +Type `make` to build the utility. diff --git a/test/util/keys.c b/test/util/keys.c new file mode 100644 index 0000000..f5e613a --- /dev/null +++ b/test/util/keys.c @@ -0,0 +1,182 @@ +#include <stdio.h> +#include <stdarg.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include <termkey.h> + +/* is c the start of a utf8 sequence? */ +#define ISUTF8(c) (((c)&0xC0)!=0x80) + +static TermKey *termkey; + +static void die(const char *errstr, ...) { + va_list ap; + va_start(ap, errstr); + vfprintf(stderr, errstr, ap); + va_end(ap); + exit(EXIT_FAILURE); +} + +static void print(const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + vfprintf(stdout, fmt, ap); + fflush(stdout); + va_end(ap); +} + +static void delay(void) { + usleep(termkey_get_waittime(termkey)*10000); +} + +static void printkey(TermKeyKey *key) { + switch (key->type) { + case TERMKEY_TYPE_UNICODE: + if (key->modifiers & TERMKEY_KEYMOD_SHIFT) + ; + if (key->modifiers & TERMKEY_KEYMOD_CTRL) + key->utf8[0] &= 0x1f; + if (key->modifiers & TERMKEY_KEYMOD_ALT) + ; + print("%s", key->utf8); + break; + case TERMKEY_TYPE_KEYSYM: + switch (key->code.sym) { + case TERMKEY_SYM_UNKNOWN: + case TERMKEY_SYM_NONE: + die("Unknown key sym\n"); + case TERMKEY_SYM_BACKSPACE: + print("\b"); + break; + case TERMKEY_SYM_TAB: + if (key->modifiers & TERMKEY_KEYMOD_SHIFT) + print("\033[Z"); + else + print("\t"); + break; + case TERMKEY_SYM_ENTER: + print("\n"); + break; + case TERMKEY_SYM_ESCAPE: + print("\033"); + delay(); + break; + case TERMKEY_SYM_SPACE: + print(" "); + break; + case TERMKEY_SYM_UP: + print("\033OA"); + break; + case TERMKEY_SYM_DOWN: + print("\033OB"); + break; + case TERMKEY_SYM_RIGHT: + print("\033OC"); + break; + case TERMKEY_SYM_LEFT: + print("\033OD"); + break; + case TERMKEY_SYM_DEL: + case TERMKEY_SYM_BEGIN: + case TERMKEY_SYM_FIND: + case TERMKEY_SYM_INSERT: + case TERMKEY_SYM_DELETE: + case TERMKEY_SYM_SELECT: + case TERMKEY_SYM_PAGEUP: + case TERMKEY_SYM_PAGEDOWN: + case TERMKEY_SYM_HOME: + case TERMKEY_SYM_END: + case TERMKEY_SYM_CANCEL: + case TERMKEY_SYM_CLEAR: + case TERMKEY_SYM_CLOSE: + case TERMKEY_SYM_COMMAND: + case TERMKEY_SYM_COPY: + case TERMKEY_SYM_EXIT: + case TERMKEY_SYM_HELP: + case TERMKEY_SYM_MARK: + case TERMKEY_SYM_MESSAGE: + case TERMKEY_SYM_MOVE: + case TERMKEY_SYM_OPEN: + case TERMKEY_SYM_OPTIONS: + case TERMKEY_SYM_PRINT: + case TERMKEY_SYM_REDO: + case TERMKEY_SYM_REFERENCE: + case TERMKEY_SYM_REFRESH: + case TERMKEY_SYM_REPLACE: + case TERMKEY_SYM_RESTART: + case TERMKEY_SYM_RESUME: + case TERMKEY_SYM_SAVE: + case TERMKEY_SYM_SUSPEND: + case TERMKEY_SYM_UNDO: + case TERMKEY_SYM_KP0: + case TERMKEY_SYM_KP1: + case TERMKEY_SYM_KP2: + case TERMKEY_SYM_KP3: + case TERMKEY_SYM_KP4: + case TERMKEY_SYM_KP5: + case TERMKEY_SYM_KP6: + case TERMKEY_SYM_KP7: + case TERMKEY_SYM_KP8: + case TERMKEY_SYM_KP9: + case TERMKEY_SYM_KPENTER: + case TERMKEY_SYM_KPPLUS: + case TERMKEY_SYM_KPMINUS: + case TERMKEY_SYM_KPMULT: + case TERMKEY_SYM_KPDIV: + case TERMKEY_SYM_KPCOMMA: + case TERMKEY_SYM_KPPERIOD: + case TERMKEY_SYM_KPEQUALS: + default: + break; + } + break; + case TERMKEY_TYPE_FUNCTION: + case TERMKEY_TYPE_MOUSE: + case TERMKEY_TYPE_POSITION: + case TERMKEY_TYPE_MODEREPORT: + case TERMKEY_TYPE_UNKNOWN_CSI: + default: + break; + } +} + +int main(int argc, char *argv[]) { + char buf[1024]; + FILE *file = stdin; + char *term = getenv("TERM"); + if (!term) + term = "xterm"; + if (!(termkey = termkey_new_abstract(term, TERMKEY_FLAG_UTF8))) + die("Failed to initialize libtermkey\n"); + while (fgets(buf, sizeof buf, file)) { + const char *keys = buf, *next; + while (*keys) { + TermKeyKey key = { 0 }; + if (*keys == '\n') { + keys++; + } else if (*keys == '<' && (next = termkey_strpkey(termkey, keys+1, &key, TERMKEY_FORMAT_VIM)) && *next == '>') { + printkey(&key); + keys = next+1; + } else { + const char *start = keys; + if (ISUTF8(*keys)) + keys++; + while (!ISUTF8(*keys)) + keys++; + size_t len = keys - start; + if (len >= sizeof(key.utf8)) + die("Too long UTF-8 sequence: %s\n", start); + // FIXME: not really correct, bug good enough for now + key.type = TERMKEY_TYPE_UNICODE; + key.modifiers = 0; + if (len > 0) + memcpy(key.utf8, start, len); + key.utf8[len] = '\0'; + printkey(&key); + } + } + } + + return 0; +} |
