From baa0d7ece4eb8401a61a0bebdb5264bf805a34c2 Mon Sep 17 00:00:00 2001 From: Jason Felice Date: Fri, 4 May 2018 12:32:40 -0400 Subject: Abort if Esc is pressed --- src/tty.c | 4 ++-- src/tty.h | 2 +- src/tty_interface.c | 56 +++++++++++++++++++++++++++++++++++++++-------------- src/tty_interface.h | 1 + 4 files changed, 46 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/tty.c b/src/tty.c index 0d53797..357b068 100644 --- a/src/tty.c +++ b/src/tty.c @@ -87,9 +87,9 @@ char tty_getchar(tty_t *tty) { } } -int tty_input_ready(tty_t *tty) { +int tty_input_ready(tty_t *tty, int pending) { fd_set readfs; - struct timeval tv = {0, 0}; + struct timeval tv = {0, pending ? 500000 : 0}; FD_ZERO(&readfs); FD_SET(tty->fdin, &readfs); select(tty->fdin + 1, &readfs, NULL, NULL, &tv); diff --git a/src/tty.h b/src/tty.h index 28c5cad..3172499 100644 --- a/src/tty.h +++ b/src/tty.h @@ -17,7 +17,7 @@ void tty_close(tty_t *tty); void tty_init(tty_t *tty, const char *tty_filename); void tty_getwinsz(tty_t *tty); char tty_getchar(tty_t *tty); -int tty_input_ready(tty_t *tty); +int tty_input_ready(tty_t *tty, int pending); void tty_setfg(tty_t *tty, int fg); void tty_setinvert(tty_t *tty); diff --git a/src/tty_interface.c b/src/tty_interface.c index a7d506e..8081f44 100644 --- a/src/tty_interface.c +++ b/src/tty_interface.c @@ -238,6 +238,7 @@ void tty_interface_init(tty_interface_t *state, tty_t *tty, choices_t *choices, state->tty = tty; state->choices = choices; state->options = options; + state->ambiguous_key_pending = 0; strcpy(state->input, ""); strcpy(state->search, ""); @@ -260,7 +261,9 @@ typedef struct { #define KEY_CTRL(key) ((const char[]){((key) - ('@')), '\0'}) -static const keybinding_t keybindings[] = {{"\x7f", action_del_char}, /* DEL */ +static const keybinding_t keybindings[] = {{"\x1b", action_exit}, /* ESC */ + {"\x7f", action_del_char}, /* DEL */ + {KEY_CTRL('H'), action_del_char}, /* Backspace (C-H) */ {KEY_CTRL('W'), action_del_word}, /* C-W */ {KEY_CTRL('U'), action_del_all}, /* C-U */ @@ -295,23 +298,40 @@ static const keybinding_t keybindings[] = {{"\x7f", action_del_char}, /* DEL */ #undef KEY_CTRL -static void handle_input(tty_interface_t *state, const char *s) { +static void handle_input(tty_interface_t *state, const char *s, int handle_ambiguous_key) { + state->ambiguous_key_pending = 0; + char *input = state->input; strcat(state->input, s); - /* See if we have matched a keybinding */ + /* Figure out if we have completed a keybinding and whether we're in the + * middle of one (both can happen, because of Esc). */ + int found_keybinding = -1; + int in_middle = 0; for (int i = 0; keybindings[i].key; i++) { - if (!strcmp(input, keybindings[i].key)) { - keybindings[i].action(state); - strcpy(input, ""); - return; - } + if (!strcmp(input, keybindings[i].key)) + found_keybinding = i; + else if (!strncmp(input, keybindings[i].key, strlen(state->input))) + in_middle = 1; } - /* Check if we are in the middle of a keybinding */ - for (int i = 0; keybindings[i].key; i++) - if (!strncmp(input, keybindings[i].key, strlen(input))) - return; + /* If we have an unambiguous keybinding, run it. */ + if (found_keybinding != -1 && (!in_middle || handle_ambiguous_key)) { + keybindings[found_keybinding].action(state); + strcpy(input, ""); + return; + } + + /* We could have a complete keybinding, or could be in the middle of one. + * We'll need to wait a few milliseconds to find out. */ + if (found_keybinding != -1 && in_middle) { + state->ambiguous_key_pending = 1; + return; + } + + /* Wait for more if we are in the middle of a keybinding */ + if (in_middle) + return; /* No matching keybinding, add to search */ for (int i = 0; input[i]; i++) @@ -328,13 +348,21 @@ int tty_interface_run(tty_interface_t *state) { for (;;) { do { char s[2] = {tty_getchar(state->tty), '\0'}; - handle_input(state, s); + handle_input(state, s, 0); if (state->exit >= 0) return state->exit; draw(state); - } while (tty_input_ready(state->tty)); + } while (tty_input_ready(state->tty, state->ambiguous_key_pending)); + + if (state->ambiguous_key_pending) { + char s[1] = ""; + handle_input(state, s, 1); + + if (state->exit >= 0) + return state->exit; + } update_state(state); } diff --git a/src/tty_interface.h b/src/tty_interface.h index 9572c3f..64af0b4 100644 --- a/src/tty_interface.h +++ b/src/tty_interface.h @@ -16,6 +16,7 @@ typedef struct { char last_search[SEARCH_SIZE_MAX + 1]; size_t cursor; + int ambiguous_key_pending; char input[32]; /* Pending input buffer */ int exit; -- cgit v1.2.3