summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKeith Smiley <keithbsmiley@gmail.com>2017-07-21 20:58:04 -0700
committerKeith Smiley <keithbsmiley@gmail.com>2017-08-13 22:31:52 -0700
commite0ce095657cc0458fa8a217d27872ec32ed814f1 (patch)
tree39be4b914ee062c09fc44eb8aa28446a009cddf0 /src
parentf1e5078925471206e1248f28b965759a109ef8eb (diff)
Support arrow key movements
Diffstat (limited to 'src')
-rw-r--r--src/tty_interface.c50
-rw-r--r--src/tty_interface.h1
2 files changed, 46 insertions, 5 deletions
diff --git a/src/tty_interface.c b/src/tty_interface.c
index fc903e6..ab20eec 100644
--- a/src/tty_interface.c
+++ b/src/tty_interface.c
@@ -93,7 +93,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);
}
@@ -131,8 +133,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) {
@@ -161,6 +170,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++)
@@ -192,8 +219,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;
}
}
@@ -201,6 +234,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, "");
@@ -233,7 +267,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 */
diff --git a/src/tty_interface.h b/src/tty_interface.h
index 438cc55..34f4e59 100644
--- a/src/tty_interface.h
+++ b/src/tty_interface.h
@@ -14,6 +14,7 @@ typedef struct {
char search[SEARCH_SIZE_MAX + 1];
char last_search[SEARCH_SIZE_MAX + 1];
+ int offset;
char input[32]; /* Pending input buffer */