Blob


1 /*
2 * Copyright (c) 2021 Omar Polo <op@omarpolo.com>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
17 #include "telescope.h"
19 #include <ctype.h>
20 #include <curses.h>
21 #include <stdlib.h>
23 #define CTRL(n) ((n)&0x1F)
25 static struct keytable {
26 char *p;
27 int k;
28 } keytable[] = {
29 { "<up>", KEY_UP },
30 { "<down>", KEY_DOWN },
31 { "<left>", KEY_LEFT },
32 { "<right>", KEY_RIGHT },
33 { "<prior>", KEY_PPAGE },
34 { "<next>", KEY_NPAGE },
35 { "<home>", KEY_HOME },
36 { "<end>", KEY_END },
37 /* ... */
38 { "del", KEY_BACKSPACE },
39 { "esc", 27 },
40 { "space", ' ' },
41 { "spc", ' ' },
42 { "enter", CTRL('m') },
43 { "ret", CTRL('m' )},
44 { "tab", CTRL('i') },
45 /* ... */
46 { NULL, 0 },
47 };
49 int
50 kbd(const char *key)
51 {
52 struct keytable *t;
54 for (t = keytable; t->p != NULL; ++t) {
55 if (has_prefix(key, t->p))
56 return t->k;
57 }
59 return *key;
60 }
62 const char *
63 unkbd(int k)
64 {
65 struct keytable *t;
67 for (t = keytable; t->p != NULL; ++t) {
68 if (k == t->k)
69 return t->p;
70 }
72 return NULL;
73 }
75 int
76 kmap_define_key(struct kmap *map, const char *key, void (*fn)(struct tab*))
77 {
78 int ctrl, meta, k;
79 struct keymap *entry;
81 again:
82 if ((ctrl = has_prefix(key, "C-")))
83 key += 2;
84 if ((meta = has_prefix(key, "M-")))
85 key += 2;
86 if (*key == '\0')
87 return 0;
88 k = kbd(key);
90 if (ctrl)
91 k = CTRL(k);
93 /* skip key & spaces */
94 while (*key != '\0' && !isspace(*key))
95 ++key;
96 while (*key != '\0' && isspace(*key))
97 ++key;
99 TAILQ_FOREACH(entry, &map->m, keymaps) {
100 if (entry->meta == meta && entry->key == k) {
101 if (*key == '\0') {
102 entry->fn = fn;
103 return 1;
105 map = &entry->map;
106 goto again;
110 if ((entry = calloc(1, sizeof(*entry))) == NULL)
111 return 0;
113 entry->meta = meta;
114 entry->key = k;
115 TAILQ_INIT(&entry->map.m);
117 if (TAILQ_EMPTY(&map->m))
118 TAILQ_INSERT_HEAD(&map->m, entry, keymaps);
119 else
120 TAILQ_INSERT_TAIL(&map->m, entry, keymaps);
122 if (*key != '\0') {
123 map = &entry->map;
124 goto again;
127 entry->fn = fn;
129 return 1;