/* * Copyright (c) 2021 Omar Polo * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "compat.h" #include #include #include #include #include "keymap.h" #include "telescope.h" #include "utils.h" #define CTRL(n) ((n)&0x1F) static struct keytable { const char *p; int k; } keytable[] = { { "", KEY_UP }, { "", KEY_DOWN }, { "", KEY_LEFT }, { "", KEY_RIGHT }, { "", KEY_PPAGE }, { "", KEY_NPAGE }, { "", KEY_HOME }, { "", KEY_END }, /* ... */ { "", KEY_F(0) }, { "", KEY_F(1) }, { "", KEY_F(2) }, { "", KEY_F(3) }, { "", KEY_F(4) }, { "", KEY_F(5) }, { "", KEY_F(6) }, { "", KEY_F(7) }, { "", KEY_F(8) }, { "", KEY_F(9) }, { "", KEY_F(10) }, { "", KEY_F(11) }, { "", KEY_F(12) }, { "", KEY_F(13) }, { "", KEY_F(14) }, { "", KEY_F(15) }, { "", KEY_F(16) }, { "", KEY_F(17) }, { "", KEY_F(18) }, { "", KEY_F(19) }, { "", KEY_F(20) }, { "", KEY_F(21) }, { "", KEY_F(22) }, { "", KEY_F(23) }, { "", KEY_F(24) }, { "", KEY_F(25) }, { "", KEY_F(26) }, { "", KEY_F(27) }, { "", KEY_F(28) }, { "", KEY_F(29) }, { "", KEY_F(30) }, { "", KEY_F(31) }, { "", KEY_F(32) }, { "", KEY_F(33) }, { "", KEY_F(34) }, { "", KEY_F(35) }, { "", KEY_F(36) }, { "", KEY_F(37) }, { "", KEY_F(38) }, { "", KEY_F(39) }, { "", KEY_F(40) }, { "", KEY_F(41) }, { "", KEY_F(42) }, { "", KEY_F(43) }, { "", KEY_F(44) }, { "", KEY_F(45) }, { "", KEY_F(46) }, { "", KEY_F(47) }, { "", KEY_F(48) }, { "", KEY_F(49) }, { "", KEY_F(50) }, { "", KEY_F(51) }, { "", KEY_F(52) }, { "", KEY_F(53) }, { "", KEY_F(54) }, { "", KEY_F(55) }, { "", KEY_F(56) }, { "", KEY_F(57) }, { "", KEY_F(58) }, { "", KEY_F(59) }, { "", KEY_F(60) }, { "", KEY_F(61) }, { "", KEY_F(62) }, { "", KEY_F(63) }, /* ... */ { "del", KEY_BACKSPACE }, { "backspace", 127 }, { "esc", '\e' }, { "space", ' ' }, { "spc", ' ' }, { "enter", CTRL('m') }, { "ret", CTRL('m' )}, { "tab", CTRL('i') }, { "backtab", KEY_BTAB }, /* ... */ { NULL, 0 }, }; int kbd(const char *key) { struct keytable *t; for (t = keytable; t->p != NULL; ++t) { if (!strncmp(key, t->p, strlen(t->p))) return t->k; } return *key; } const char * unkbd(int k) { struct keytable *t; for (t = keytable; t->p != NULL; ++t) { if (k == t->k) return t->p; } return NULL; } int kmap_define_key(struct kmap *map, const char *key, void (*fn)(struct buffer*)) { int ctrl, meta, k; struct keymap *entry; again: if ((ctrl = !strncmp(key, "C-", 2))) key += 2; if ((meta = !strncmp(key, "M-", 2))) key += 2; if (*key == '\0') return 0; k = kbd(key); if (ctrl) k = CTRL(k); /* skip key & spaces */ while (*key != '\0' && !isspace(*key)) ++key; while (*key != '\0' && isspace(*key)) ++key; TAILQ_FOREACH(entry, &map->m, keymaps) { if (entry->meta == meta && entry->key == k) { if (*key == '\0') { entry->fn = fn; return 1; } map = &entry->map; goto again; } } if ((entry = calloc(1, sizeof(*entry))) == NULL) return 0; entry->meta = meta; entry->key = k; TAILQ_INIT(&entry->map.m); TAILQ_INSERT_TAIL(&map->m, entry, keymaps); if (*key != '\0') { map = &entry->map; goto again; } entry->fn = fn; return 1; } int lookup_key(struct kmap **map, struct thiskey *key, struct buffer *buf) { struct keymap *k; TAILQ_FOREACH(k, &(*map)->m, keymaps) { if (k->meta == key->meta && k->key == key->key) { if (k->fn == NULL) { *map = &k->map; return LK_ADVANCED_MAP; } else { k->fn(buf); return LK_MATCHED; } } } return LK_UNBOUND; }