summaryrefslogtreecommitdiff
path: root/src/input.c
diff options
context:
space:
mode:
authorPhil Jones <philj56@gmail.com>2022-12-20 23:53:20 +0000
committerPhil Jones <philj56@gmail.com>2022-12-21 00:15:16 +0000
commit6c47cf7892d0f212b04e7b798e53c120f51022d7 (patch)
treec44b910e059d5bdcf991b2239de8d29cb007bed6 /src/input.c
parent108550fcf8d3ed8664c0e05defceaf20b4d2b49e (diff)
Add text cursor support.
This turned out to be much more complex than anticipated, and the potential for bugs is therefore quite high.
Diffstat (limited to 'src/input.c')
-rw-r--r--src/input.c109
1 files changed, 87 insertions, 22 deletions
diff --git a/src/input.c b/src/input.c
index 9be16e9..be65e24 100644
--- a/src/input.c
+++ b/src/input.c
@@ -16,6 +16,8 @@ static void clear_input(struct tofi *tofi);
static void paste(struct tofi *tofi);
static void select_previous_result(struct tofi *tofi);
static void select_next_result(struct tofi *tofi);
+static void next_cursor_or_result(struct tofi *tofi);
+static void previous_cursor_or_result(struct tofi *tofi);
static void reset_selection(struct tofi *tofi);
void input_handle_keypress(struct tofi *tofi, xkb_keycode_t keycode)
@@ -62,6 +64,10 @@ void input_handle_keypress(struct tofi *tofi, xkb_keycode_t keycode)
)
{
paste(tofi);
+ } else if (sym == XKB_KEY_Left) {
+ previous_cursor_or_result(tofi);
+ } else if (sym == XKB_KEY_Right) {
+ next_cursor_or_result(tofi);
} else if (sym == XKB_KEY_Up || sym == XKB_KEY_Left || sym == XKB_KEY_ISO_Left_Tab
|| (key == KEY_K
&& xkb_state_mod_name_is_active(
@@ -122,24 +128,38 @@ void add_character(struct tofi *tofi, xkb_keycode_t keycode)
keycode,
buf,
sizeof(buf));
- entry->input_utf32[entry->input_utf32_length] = utf8_to_utf32(buf);
- entry->input_utf32_length++;
- entry->input_utf32[entry->input_utf32_length] = U'\0';
- memcpy(&entry->input_utf8[entry->input_utf8_length],
- buf,
- N_ELEM(buf));
- entry->input_utf8_length += len;
- if (entry->drun) {
- struct string_ref_vec results = desktop_vec_filter(&entry->apps, entry->input_utf8, tofi->fuzzy_match);
- string_ref_vec_destroy(&entry->results);
- entry->results = results;
+ if (entry->cursor_position == entry->input_utf32_length) {
+ entry->input_utf32[entry->input_utf32_length] = utf8_to_utf32(buf);
+ entry->input_utf32_length++;
+ entry->input_utf32[entry->input_utf32_length] = U'\0';
+ memcpy(&entry->input_utf8[entry->input_utf8_length],
+ buf,
+ N_ELEM(buf));
+ entry->input_utf8_length += len;
+
+ if (entry->drun) {
+ struct string_ref_vec results = desktop_vec_filter(&entry->apps, entry->input_utf8, tofi->fuzzy_match);
+ string_ref_vec_destroy(&entry->results);
+ entry->results = results;
+ } else {
+ struct string_ref_vec tmp = entry->results;
+ entry->results = string_ref_vec_filter(&entry->results, entry->input_utf8, tofi->fuzzy_match);
+ string_ref_vec_destroy(&tmp);
+ }
+
+ reset_selection(tofi);
} else {
- struct string_ref_vec tmp = entry->results;
- entry->results = string_ref_vec_filter(&entry->results, entry->input_utf8, tofi->fuzzy_match);
- string_ref_vec_destroy(&tmp);
+ for (size_t i = entry->input_utf32_length; i > entry->cursor_position; i--) {
+ entry->input_utf32[i] = entry->input_utf32[i - 1];
+ }
+ entry->input_utf32[entry->cursor_position] = utf8_to_utf32(buf);
+ entry->input_utf32_length++;
+ entry->input_utf32[entry->input_utf32_length] = U'\0';
+
+ input_refresh_results(tofi);
}
- reset_selection(tofi);
+ entry->cursor_position++;
}
void input_refresh_results(struct tofi *tofi)
@@ -173,8 +193,20 @@ void delete_character(struct tofi *tofi)
return;
}
- entry->input_utf32_length--;
- entry->input_utf32[entry->input_utf32_length] = U'\0';
+ if (entry->cursor_position == 0) {
+ return;
+ } else if (entry->cursor_position == entry->input_utf32_length) {
+ entry->cursor_position--;
+ entry->input_utf32_length--;
+ entry->input_utf32[entry->input_utf32_length] = U'\0';
+ } else {
+ for (size_t i = entry->cursor_position - 1; i < entry->input_utf32_length - 1; i++) {
+ entry->input_utf32[i] = entry->input_utf32[i + 1];
+ }
+ entry->cursor_position--;
+ entry->input_utf32_length--;
+ entry->input_utf32[entry->input_utf32_length] = U'\0';
+ }
input_refresh_results(tofi);
}
@@ -183,19 +215,26 @@ void delete_word(struct tofi *tofi)
{
struct entry *entry = &tofi->window.entry;
- if (entry->input_utf32_length == 0) {
+ if (entry->cursor_position == 0) {
/* No input to delete. */
return;
}
- while (entry->input_utf32_length > 0 && utf32_isspace(entry->input_utf32[entry->input_utf32_length - 1])) {
- entry->input_utf32_length--;
+ uint32_t new_cursor_pos = entry->cursor_position;
+ while (new_cursor_pos > 0 && utf32_isspace(entry->input_utf32[new_cursor_pos - 1])) {
+ new_cursor_pos--;
}
- while (entry->input_utf32_length > 0 && !utf32_isspace(entry->input_utf32[entry->input_utf32_length - 1])) {
- entry->input_utf32_length--;
+ while (new_cursor_pos > 0 && !utf32_isspace(entry->input_utf32[new_cursor_pos - 1])) {
+ new_cursor_pos--;
+ }
+ uint32_t new_length = entry->input_utf32_length - (entry->cursor_position - new_cursor_pos);
+ for (size_t i = 0; i < new_length; i++) {
+ entry->input_utf32[new_cursor_pos + i] = entry->input_utf32[entry->cursor_position + i];
}
+ entry->input_utf32_length = new_length;
entry->input_utf32[entry->input_utf32_length] = U'\0';
+ entry->cursor_position = new_cursor_pos;
input_refresh_results(tofi);
}
@@ -203,6 +242,7 @@ void clear_input(struct tofi *tofi)
{
struct entry *entry = &tofi->window.entry;
+ entry->cursor_position = 0;
entry->input_utf32_length = 0;
entry->input_utf32[0] = U'\0';
@@ -270,3 +310,28 @@ void select_next_result(struct tofi *tofi)
entry->last_num_results_drawn = entry->num_results_drawn;
}
}
+
+void previous_cursor_or_result(struct tofi *tofi)
+{
+ struct entry *entry = &tofi->window.entry;
+
+ if (entry->cursor_theme.show
+ && entry->selection == 0
+ && entry->cursor_position > 0) {
+ entry->cursor_position--;
+ } else {
+ select_previous_result(tofi);
+ }
+}
+
+void next_cursor_or_result(struct tofi *tofi)
+{
+ struct entry *entry = &tofi->window.entry;
+
+ if (entry->cursor_theme.show
+ && entry->cursor_position < entry->input_utf32_length) {
+ entry->cursor_position++;
+ } else {
+ select_next_result(tofi);
+ }
+}