Browse code

add utf-8 support to input, fixes #21

- 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

syrrim authored on 23/04/2018 05:25:48
Showing 1 changed files

... ...
@@ -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 */