diff options
-rw-r--r-- | src/tty.c | 8 | ||||
-rw-r--r-- | src/tty.h | 1 | ||||
-rw-r--r-- | src/tty_interface.c | 49 |
3 files changed, 41 insertions, 17 deletions
@@ -86,6 +86,14 @@ char tty_getchar(tty_t *tty) { } } +int tty_input_ready(tty_t *tty) { + fd_set readfs; + struct timeval tv = {0, 0}; + FD_SET(tty->fdin, &readfs); + select(tty->fdin + 1, &readfs, NULL, NULL, &tv); + return FD_ISSET(tty->fdin, &readfs); +} + static void tty_sgr(tty_t *tty, int code) { tty_printf(tty, "%c%c%im", 0x1b, '[', code); } @@ -17,6 +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); 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 9044723..eddd510 100644 --- a/src/tty_interface.c +++ b/src/tty_interface.c @@ -23,7 +23,7 @@ static void clear(tty_interface_t *state) { static void draw_match(tty_interface_t *state, const char *choice, int selected) { tty_t *tty = state->tty; options_t *options = state->options; - char *search = state->search; + char *search = state->last_search; int n = strlen(search); size_t positions[n + 1]; @@ -87,7 +87,21 @@ static void draw(tty_interface_t *state) { tty_flush(tty); } +static void update_search(tty_interface_t *state) { + choices_search(state->choices, state->search); + strcpy(state->last_search, state->search); +} + +void update_state(tty_interface_t *state) { + if (strcmp(state->last_search, state->search)) { + update_search(state); + draw(state); + } +} + static void action_emit(tty_interface_t *state) { + update_state(state); + /* Reset the tty as close as possible to the previous state */ clear(state); @@ -124,24 +138,29 @@ static void action_del_all(tty_interface_t *state) { } static void action_prev(tty_interface_t *state) { + update_state(state); choices_prev(state->choices); } static void action_next(tty_interface_t *state) { + update_state(state); choices_next(state->choices); } static void action_pageup(tty_interface_t *state) { + update_state(state); for(size_t i = 0; i < state->options->num_lines && state->choices->selection > 0; i++) choices_prev(state->choices); } static void action_pagedown(tty_interface_t *state) { + update_state(state); for(size_t i = 0; i < state->options->num_lines && state->choices->selection < state->choices->available-1; i++) choices_next(state->choices); } static void action_autocomplete(tty_interface_t *state) { + update_state(state); strncpy(state->search, choices_get(state->choices, state->choices->selection), SEARCH_SIZE_MAX); } @@ -161,16 +180,6 @@ static void append_search(tty_interface_t *state, char ch) { } } -static void update_search(tty_interface_t *state) { - choices_search(state->choices, state->search); - strcpy(state->last_search, state->search); -} - -void update_state(tty_interface_t *state) { - if (strcmp(state->last_search, state->search)) - update_search(state); -} - void tty_interface_init(tty_interface_t *state, tty_t *tty, choices_t *choices, options_t *options) { state->tty = tty; state->choices = choices; @@ -216,8 +225,9 @@ static const keybinding_t keybindings[] = {{"\x7f", action_del_char}, /* DEL */ #undef KEY_CTRL -void handle_input(tty_interface_t *state) { +void handle_input(tty_interface_t *state, const char *s) { char *input = state->input; + strcat(state->input, s); /* See if we have matched a keybinding */ for (int i = 0; keybindings[i].key; i++) { @@ -243,13 +253,18 @@ void handle_input(tty_interface_t *state) { } int tty_interface_run(tty_interface_t *state) { - while (state->exit < 0) { - draw(state); + draw(state); + + for (;;) { + do { + char s[2] = {tty_getchar(state->tty), '\0'}; + handle_input(state, s); - char s[2] = {tty_getchar(state->tty), '\0'}; - strcat(state->input, s); + if (state->exit >= 0) + return state->exit; - handle_input(state); + draw(state); + } while (tty_input_ready(state->tty)); update_state(state); } |