- non ascii bytes won't be ignored
- one can seek over and delete whole utf-8 codepoints at a time
- the cursor will be positioned properly around double width chars
| ... | ... |
@@ -7,6 +7,14 @@ |
| 7 | 7 |
#include "tty_interface.h" |
| 8 | 8 |
#include "../config.h" |
| 9 | 9 |
|
| 10 |
+static int isprint_unicode(char c){
|
|
| 11 |
+ return isprint(c) || c & (1<<7); |
|
| 12 |
+} |
|
| 13 |
+ |
|
| 14 |
+static int is_boundary(char c) {
|
|
| 15 |
+ return ~c & (1<<7) || c & (1<<6); |
|
| 16 |
+} |
|
| 17 |
+ |
|
| 10 | 18 |
static void clear(tty_interface_t *state) {
|
| 11 | 19 |
tty_t *tty = state->tty; |
| 12 | 20 |
|
| ... | ... |
@@ -95,7 +103,10 @@ static void draw(tty_interface_t *state) {
|
| 95 | 103 |
tty_moveup(tty, num_lines); |
| 96 | 104 |
} |
| 97 | 105 |
|
| 98 |
- tty_setcol(tty, strlen(options->prompt) + state->cursor); |
|
| 106 |
+ tty_setcol(tty, 0); |
|
| 107 |
+ fputs(options->prompt, tty->fout); |
|
| 108 |
+ for(size_t i=0; i<state->cursor; i++) |
|
| 109 |
+ fputc(state->search[i], tty->fout); |
|
| 99 | 110 |
tty_flush(tty); |
| 100 | 111 |
} |
| 101 | 112 |
|
| ... | ... |
@@ -138,9 +149,13 @@ static void action_del_char(tty_interface_t *state) {
|
| 138 | 149 |
if(state->cursor == 0) {
|
| 139 | 150 |
return; |
| 140 | 151 |
} |
| 152 |
+ size_t original_cursor = state->cursor; |
|
| 141 | 153 |
|
| 142 | 154 |
state->cursor--; |
| 143 |
- memmove(&state->search[state->cursor], &state->search[state->cursor + 1], length - state->cursor); |
|
| 155 |
+ while(!is_boundary(state->search[state->cursor]) && state->cursor) |
|
| 156 |
+ state->cursor--; |
|
| 157 |
+ |
|
| 158 |
+ memmove(&state->search[state->cursor], &state->search[original_cursor], length - original_cursor + 1); |
|
| 144 | 159 |
} |
| 145 | 160 |
} |
| 146 | 161 |
|
| ... | ... |
@@ -178,13 +193,19 @@ static void action_next(tty_interface_t *state) {
|
| 178 | 193 |
} |
| 179 | 194 |
|
| 180 | 195 |
static void action_left(tty_interface_t *state) {
|
| 181 |
- if (state->cursor > 0) |
|
| 196 |
+ if (state->cursor > 0){
|
|
| 182 | 197 |
state->cursor--; |
| 198 |
+ while(!is_boundary(state->search[state->cursor]) && state->cursor) |
|
| 199 |
+ state->cursor--; |
|
| 200 |
+ } |
|
| 183 | 201 |
} |
| 184 | 202 |
|
| 185 | 203 |
static void action_right(tty_interface_t *state) {
|
| 186 |
- if (state->cursor < strlen(state->search)) |
|
| 204 |
+ if (state->cursor < strlen(state->search)){
|
|
| 187 | 205 |
state->cursor++; |
| 206 |
+ while(!is_boundary(state->search[state->cursor])) |
|
| 207 |
+ state->cursor++; |
|
| 208 |
+ } |
|
| 188 | 209 |
} |
| 189 | 210 |
|
| 190 | 211 |
static void action_beginning(tty_interface_t *state) {
|
| ... | ... |
@@ -315,7 +336,7 @@ static void handle_input(tty_interface_t *state, const char *s) {
|
| 315 | 336 |
|
| 316 | 337 |
/* No matching keybinding, add to search */ |
| 317 | 338 |
for (int i = 0; input[i]; i++) |
| 318 |
- if (isprint(input[i])) |
|
| 339 |
+ if (isprint_unicode(input[i])) |
|
| 319 | 340 |
append_search(state, input[i]); |
| 320 | 341 |
|
| 321 | 342 |
/* We have processed the input, so clear it */ |