commit 67c8ed7f496533b30422532ac86a57b02265b1ab from: Omar Polo date: Sat Mar 13 18:44:50 2021 UTC move keymap funcs in its own file commit - 6d413abf961327c226d341c8bafe5c9a6e6ef88c commit + 67c8ed7f496533b30422532ac86a57b02265b1ab blob - 6c5fc4fc2692a025d295b8ea8836e249e48290c1 blob + ad9d7c241a992e0548e4aa80c463f112d0aec7c5 --- Makefile.am +++ Makefile.am @@ -4,6 +4,7 @@ telescope_SOURCES = compat.h \ compat/*.[ch] \ gemini.c \ gemtext.c \ + keymap.c \ mime.c \ pages.c \ parser.c \ blob - /dev/null blob + 95334c2303461185e1133845affdba1ca63de1c1 (mode 644) --- /dev/null +++ keymap.c @@ -0,0 +1,131 @@ +/* + * 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 "telescope.h" + +#include +#include +#include + +#define CTRL(n) ((n)&0x1F) + +struct keytable { + char *p; + int k; +} keytable[] = { + { "", KEY_UP }, + { "", KEY_DOWN }, + { "", KEY_LEFT }, + { "", KEY_RIGHT }, + { "", KEY_PPAGE }, + { "", KEY_NPAGE }, + { "", KEY_HOME }, + { "", KEY_END }, + /* ... */ + { "del", KEY_BACKSPACE }, + { "esc", 27 }, + { "space", ' ' }, + { "spc", ' ' }, + { "enter", CTRL('m') }, + { "ret", CTRL('m' )}, + { "tab", CTRL('i') }, + /* ... */ + { NULL, 0 }, +}; + +int +kbd(const char *key) +{ + struct keytable *t; + + for (t = keytable; t->p != NULL; ++t) { + if (has_prefix(key, 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 tab*)) +{ + int ctrl, meta, k; + struct keymap *entry; + +again: + if ((ctrl = has_prefix(key, "C-"))) + key += 2; + if ((meta = has_prefix(key, "M-"))) + 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); + + if (TAILQ_EMPTY(&map->m)) + TAILQ_INSERT_HEAD(&map->m, entry, keymaps); + else + TAILQ_INSERT_TAIL(&map->m, entry, keymaps); + + if (*key != '\0') { + map = &entry->map; + goto again; + } + + entry->fn = fn; + + return 1; +} + blob - 63c9cc3e4fa8ef04821a5fc9a38f8eb4a981a1b4 blob + 6dcb8f235e8c26e0188846169cfb36cd4ea4a490 --- telescope.h +++ telescope.h @@ -109,6 +109,20 @@ struct proto { void (*loadfn)(struct tab*, const char*); }; +struct kmap { + TAILQ_HEAD(map, keymap) m; + void (*unhandled_input)(void); +}; + +struct keymap { + int meta; + int key; + struct kmap map; + void (*fn)(struct tab*); + + TAILQ_ENTRY(keymap) keymaps; +}; + extern struct event imsgev; /* gemini.c */ @@ -117,6 +131,11 @@ int client_main(struct imsgbuf *b); /* gemtext.c */ void gemtext_initparser(struct parser*); +/* keymap.c */ +int kbd(const char*); +const char *unkbd(int); +int kmap_define_key(struct kmap*, const char*, void(*)(struct tab*)); + /* mime.c */ int setup_parser_for(struct tab*); blob - 13f4cfecae972a2d9edca803451b11921edd1409 blob + 8ff7ebb98d769f947eab3b294d0b3b08c7d4916b --- ui.c +++ ui.c @@ -78,8 +78,6 @@ struct minibuf_histhead; static struct event stdioev, winchev; -static int kbd(const char*); -static void kmap_define_key(struct kmap*, const char*, void(*)(struct tab*)); static void load_default_keys(void); static int push_line(struct tab*, const struct line*, const char*, size_t, int); static void empty_vlist(struct tab*); @@ -185,52 +183,12 @@ struct ui_state { }; static char keybuf[64]; - -#define CTRL(n) ((n)&0x1F) - -struct keytable { - char *p; - int k; -} keytable[] = { - { "", KEY_UP }, - { "", KEY_DOWN }, - { "", KEY_LEFT }, - { "", KEY_RIGHT }, - { "", KEY_PPAGE }, - { "", KEY_NPAGE }, - { "", KEY_HOME }, - { "", KEY_END }, - /* ... */ - { "del", KEY_BACKSPACE }, - { "esc", 27 }, - { "space", ' ' }, - { "spc", ' ' }, - { "enter", CTRL('m') }, - { "ret", CTRL('m' )}, - { "tab", CTRL('i') }, - /* ... */ - { NULL, 0 }, -}; - -struct kmap { - TAILQ_HEAD(map, keymap) m; - void (*unhandled_input)(void); -}; struct kmap global_map, minibuffer_map, *current_map, *base_map; -struct keymap { - int meta; - int key; - struct kmap map; - void (*fn)(struct tab*); - - TAILQ_ENTRY(keymap) keymaps; -}; - /* TODO: limit to a maximum number of entries */ struct minibuf_histhead { TAILQ_HEAD(mhisthead, minibuf_hist) head; @@ -292,97 +250,18 @@ struct line_face { [LINE_PRE_END] = { 0 }, }; -static int -kbd(const char *key) -{ - struct keytable *t; - - for (t = keytable; t->p != NULL; ++t) { - if (has_prefix(key, t->p)) - return t->k; - } - - return *key; -} - -static const char * -unkbd(int k) -{ - struct keytable *t; - - for (t = keytable; t->p != NULL; ++t) { - if (k == t->k) - return t->p; - } - - return NULL; -} - -static void -kmap_define_key(struct kmap *map, const char *key, void (*fn)(struct tab*)) -{ - int ctrl, meta, k; - struct keymap *entry; - -again: - if ((ctrl = has_prefix(key, "C-"))) - key += 2; - if ((meta = has_prefix(key, "M-"))) - key += 2; - if (*key == '\0') - _exit(1); - 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; - } - map = &entry->map; - goto again; - } - } - - if ((entry = calloc(1, sizeof(*entry))) == NULL) - abort(); - - entry->meta = meta; - entry->key = k; - TAILQ_INIT(&entry->map.m); - - if (TAILQ_EMPTY(&map->m)) - TAILQ_INSERT_HEAD(&map->m, entry, keymaps); - else - TAILQ_INSERT_TAIL(&map->m, entry, keymaps); - - if (*key != '\0') { - map = &entry->map; - goto again; - } - - entry->fn = fn; -} - static inline void global_set_key(const char *key, void (*fn)(struct tab*)) { - kmap_define_key(&global_map, key, fn); + if (!kmap_define_key(&global_map, key, fn)) + _exit(1); } static inline void minibuffer_set_key(const char *key, void (*fn)(struct tab*)) { - kmap_define_key(&minibuffer_map, key, fn); + if (!kmap_define_key(&minibuffer_map, key, fn)) + _exit(1); } static void