diff options
Diffstat (limited to 'src/tty_interface.c')
-rw-r--r-- | src/tty_interface.c | 69 |
1 files changed, 44 insertions, 25 deletions
diff --git a/src/tty_interface.c b/src/tty_interface.c index 8081f44..f6aeef0 100644 --- a/src/tty_interface.c +++ b/src/tty_interface.c @@ -7,6 +7,14 @@ #include "tty_interface.h" #include "../config.h" +static int isprint_unicode(char c) { + return isprint(c) || c & (1 << 7); +} + +static int is_boundary(char c) { + return ~c & (1 << 7) || c & (1 << 6); +} + static void clear(tty_interface_t *state) { tty_t *tty = state->tty; @@ -34,34 +42,32 @@ static void draw_match(tty_interface_t *state, const char *choice, int selected) score_t score = match_positions(search, choice, &positions[0]); - size_t maxwidth = tty_getwidth(tty); - - if (options->show_scores && maxwidth >= 9) { + if (options->show_scores) { if (score == SCORE_MIN) { tty_printf(tty, "( ) "); } else { tty_printf(tty, "(%5.2f) ", score); } - maxwidth -= 8; } if (selected) +#ifdef TTY_SELECTION_UNDERLINE + tty_setunderline(tty); +#else tty_setinvert(tty); +#endif + tty_setnowrap(tty); for (size_t i = 0, p = 0; choice[i] != '\0'; i++) { - if (i + 1 < maxwidth) { - if (positions[p] == i) { - tty_setfg(tty, TTY_COLOR_HIGHLIGHT); - p++; - } else { - tty_setfg(tty, TTY_COLOR_NORMAL); - } - tty_printf(tty, "%c", choice[i]); + if (positions[p] == i) { + tty_setfg(tty, TTY_COLOR_HIGHLIGHT); + p++; } else { - tty_printf(tty, "$"); - break; + tty_setfg(tty, TTY_COLOR_NORMAL); } + tty_printf(tty, "%c", choice[i]); } + tty_setwrap(tty); tty_setnormal(tty); } @@ -95,7 +101,10 @@ static void draw(tty_interface_t *state) { tty_moveup(tty, num_lines); } - tty_setcol(tty, strlen(options->prompt) + state->cursor); + tty_setcol(tty, 0); + fputs(options->prompt, tty->fout); + for (size_t i = 0; i < state->cursor; i++) + fputc(state->search[i], tty->fout); tty_flush(tty); } @@ -135,12 +144,16 @@ static void action_emit(tty_interface_t *state) { static void action_del_char(tty_interface_t *state) { if (*state->search) { size_t length = strlen(state->search); - if(state->cursor == 0) { + if (state->cursor == 0) { return; } + size_t original_cursor = state->cursor; state->cursor--; - memmove(&state->search[state->cursor], &state->search[state->cursor + 1], length - state->cursor); + while (!is_boundary(state->search[state->cursor]) && state->cursor) + state->cursor--; + + memmove(&state->search[state->cursor], &state->search[original_cursor], length - original_cursor + 1); } } @@ -169,7 +182,7 @@ static void action_prev(tty_interface_t *state) { } static void action_ignore(tty_interface_t *state) { - (void) state; + (void)state; } static void action_next(tty_interface_t *state) { @@ -178,13 +191,19 @@ static void action_next(tty_interface_t *state) { } static void action_left(tty_interface_t *state) { - if (state->cursor > 0) + if (state->cursor > 0) { state->cursor--; + while (!is_boundary(state->search[state->cursor]) && state->cursor) + state->cursor--; + } } static void action_right(tty_interface_t *state) { - if (state->cursor < strlen(state->search)) + if (state->cursor < strlen(state->search)) { state->cursor++; + while (!is_boundary(state->search[state->cursor])) + state->cursor++; + } } static void action_beginning(tty_interface_t *state) { @@ -197,13 +216,13 @@ static void action_end(tty_interface_t *state) { 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++) + 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++) + for (size_t i = 0; i < state->options->num_lines && state->choices->selection < state->choices->available - 1; i++) choices_next(state->choices); } @@ -273,8 +292,8 @@ static const keybinding_t keybindings[] = {{"\x1b", action_exit}, /* ESC * {KEY_CTRL('M'), action_emit}, /* CR */ {KEY_CTRL('P'), action_prev}, /* C-P */ {KEY_CTRL('N'), action_next}, /* C-N */ - {KEY_CTRL('K'), action_prev}, /* C-J */ - {KEY_CTRL('J'), action_next}, /* C-K */ + {KEY_CTRL('K'), action_prev}, /* C-K */ + {KEY_CTRL('J'), action_next}, /* C-J */ {KEY_CTRL('A'), action_beginning}, /* C-A */ {KEY_CTRL('E'), action_end}, /* C-E */ @@ -335,7 +354,7 @@ static void handle_input(tty_interface_t *state, const char *s, int handle_ambig /* No matching keybinding, add to search */ for (int i = 0; input[i]; i++) - if (isprint(input[i])) + if (isprint_unicode(input[i])) append_search(state, input[i]); /* We have processed the input, so clear it */ |