summaryrefslogtreecommitdiff
path: root/src/tty_interface.c
diff options
context:
space:
mode:
authorJohn Hawthorn <john.hawthorn@gmail.com>2017-10-07 21:33:40 -0700
committerGitHub <noreply@github.com>2017-10-07 21:33:40 -0700
commit99fb33f60e7ae4cfdb7a887f9b1596b291643fbf (patch)
tree2118c169932bf05a0df731c2d88c1599c0af3741 /src/tty_interface.c
parent34bf44e9cb4a0485f2a991939227fef5e5e6fde6 (diff)
parente0ce095657cc0458fa8a217d27872ec32ed814f1 (diff)
Merge pull request #46 from keith/ks/arrow-keys
Support arrow key movements
Diffstat (limited to 'src/tty_interface.c')
-rw-r--r--src/tty_interface.c50
1 files changed, 45 insertions, 5 deletions
diff --git a/src/tty_interface.c b/src/tty_interface.c
index 9f9eb49..39b96aa 100644
--- a/src/tty_interface.c
+++ b/src/tty_interface.c
@@ -94,7 +94,9 @@ static void draw(tty_interface_t *state) {
if (num_lines > 0) {
tty_moveup(tty, num_lines);
}
- tty_setcol(tty, strlen(options->prompt) + strlen(state->search));
+
+ int length = strlen(options->prompt) + strlen(state->search);
+ tty_setcol(tty, length + state->offset);
tty_flush(tty);
}
@@ -132,8 +134,15 @@ static void action_emit(tty_interface_t *state) {
}
static void action_del_char(tty_interface_t *state) {
- if (*state->search)
- state->search[strlen(state->search) - 1] = '\0';
+ if (*state->search) {
+ int length = strlen(state->search);
+ int index = length + state->offset - 1;
+ if (index < 0) {
+ return;
+ }
+
+ memmove(&state->search[index], &state->search[index + 1], length - index);
+ }
}
static void action_del_word(tty_interface_t *state) {
@@ -162,6 +171,24 @@ static void action_next(tty_interface_t *state) {
choices_next(state->choices);
}
+static void action_left(tty_interface_t *state) {
+ if ((unsigned long)abs(state->offset) < strlen(state->search))
+ state->offset--;
+}
+
+static void action_right(tty_interface_t *state) {
+ if (state->offset < 0)
+ state->offset++;
+}
+
+static void action_beginning(tty_interface_t *state) {
+ state->offset = -strlen(state->search);
+}
+
+static void action_end(tty_interface_t *state) {
+ state->offset = 0;
+}
+
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++)
@@ -193,8 +220,14 @@ static void append_search(tty_interface_t *state, char ch) {
char *search = state->search;
size_t search_size = strlen(search);
if (search_size < SEARCH_SIZE_MAX) {
- search[search_size++] = ch;
- search[search_size] = '\0';
+ int location = state->offset + search_size;
+ for (int i = search_size; i >= 0; i--) {
+ if (i >= location) {
+ search[i + 1] = search[i];
+ }
+ }
+
+ search[location] = ch;
}
}
@@ -202,6 +235,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->offset = 0;
strcpy(state->input, "");
strcpy(state->search, "");
@@ -234,7 +268,13 @@ static const keybinding_t keybindings[] = {{"\x7f", action_del_char}, /* DEL */
{KEY_CTRL('N'), action_next}, /* C-N */
{KEY_CTRL('K'), action_prev}, /* C-J */
{KEY_CTRL('J'), action_next}, /* C-K */
+ {KEY_CTRL('A'), action_beginning}, /* C-A */
+ {KEY_CTRL('E'), action_end}, /* C-E */
+ {"\x1bOD", action_left}, /* LEFT */
+ {"\x1b[D", action_left}, /* LEFT */
+ {"\x1bOC", action_right}, /* RIGHT */
+ {"\x1b[C", action_right}, /* RIGHT */
{"\x1b[A", action_prev}, /* UP */
{"\x1bOA", action_prev}, /* UP */
{"\x1b[B", action_next}, /* DOWN */