summaryrefslogtreecommitdiff
path: root/src/tty_interface.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tty_interface.c')
-rw-r--r--src/tty_interface.c69
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 */