@@ -92,12 +92,21 @@ typedef struct _readline_t {
92
92
int escape_seq ;
93
93
int hist_cur ;
94
94
size_t cursor_pos ;
95
+ uint8_t utf8_cont_chars ;
95
96
char escape_seq_buf [1 ];
96
97
const char * prompt ;
97
98
} readline_t ;
98
99
99
100
STATIC readline_t rl ;
100
101
102
+ int readline_count_cont_byte (char * start , char * end ) {
103
+ int count = 0 ;
104
+ for (char * pos = start ; pos < end ; pos ++ ) {
105
+ count += UTF8_IS_CONT (* pos );
106
+ }
107
+ return count ;
108
+ }
109
+
101
110
int readline_process_char (int c ) {
102
111
size_t last_line_len = rl .line -> len ;
103
112
int cont_chars = 0 ;
@@ -180,8 +189,7 @@ int readline_process_char(int c) {
180
189
#endif
181
190
182
191
// Check if we have moved into a UTF-8 continuation byte
183
- while (UTF8_IS_CONT (rl .line -> buf [rl .cursor_pos - nspace ]) &&
184
- rl .cursor_pos - nspace > rl .orig_line_len ) {
192
+ while (UTF8_IS_CONT (rl .line -> buf [rl .cursor_pos - nspace ])) {
185
193
nspace ++ ;
186
194
cont_chars ++ ;
187
195
}
@@ -223,27 +231,23 @@ int readline_process_char(int c) {
223
231
}else if (c >= 128 ) {
224
232
// utf-8 character
225
233
if (c >= 0xc0 && c < 0xf8 ) {
226
- // First Code Point
234
+ // Lead code point
227
235
vstr_ins_char (rl .line , rl .cursor_pos , c );
236
+ rl .utf8_cont_chars = 0 ;
228
237
}else if (UTF8_IS_CONT (c )) {
229
- char fcp = rl .line -> buf [rl .cursor_pos ];
230
- if (fcp >= 0xc0 && fcp < 0xf8 ) {
231
- int need = (0xe5 >> ((fcp >> 3 ) & 0x6 )) & 3 ; // From unicode.c L195
232
- cont_chars ++ ;
233
- while (UTF8_IS_CONT (rl .line -> buf [rl .cursor_pos + cont_chars ]) &&
234
- rl .cursor_pos + cont_chars < rl .line -> len && cont_chars < need ) {
235
- cont_chars ++ ;
236
- }
237
- vstr_ins_char (rl .line , rl .cursor_pos + cont_chars , c );
238
- if (cont_chars == need ) {
238
+ char lcp = rl .line -> buf [rl .cursor_pos ];
239
+ // Check for valid lead code point
240
+ if (lcp >= 0xc0 && lcp < 0xf8 ) {
241
+ rl .utf8_cont_chars += 1 ;
242
+ vstr_ins_char (rl .line , rl .cursor_pos + rl .utf8_cont_chars , c );
243
+ // set redraw parameters if we have the entire character
244
+ uint8_t need = (0xe5 >> ((lcp >> 3 ) & 0x6 )) & 3 ; // From unicode.c L195
245
+ if (rl .utf8_cont_chars == need ) {
239
246
redraw_from_cursor = true;
240
- redraw_step_forward = cont_chars + 1 ;
247
+ redraw_step_forward = rl .utf8_cont_chars + 1 ;
248
+ cont_chars = rl .utf8_cont_chars ;
241
249
}
242
- }else {
243
- //ignore, for now (invalid first code point)
244
250
}
245
- }else {
246
- // ignore, invalid
247
251
}
248
252
}
249
253
} else if (rl .escape_seq == ESEQ_ESC ) {
@@ -270,12 +274,8 @@ int readline_process_char(int c) {
270
274
#endif
271
275
// up arrow
272
276
if (rl .hist_cur + 1 < (int )READLINE_HIST_SIZE && MP_STATE_PORT (readline_hist )[rl .hist_cur + 1 ] != NULL ) {
273
- for (char * ch = rl .line -> buf + rl .cursor_pos - 1 ; ch > rl .line -> buf + rl .orig_line_len ; ch -- ) {
274
- // printf("char: %d\n", ch);
275
- if (UTF8_IS_CONT (* ch )) {
276
- cont_chars ++ ;
277
- }
278
- }
277
+ // Check for continuation characters through the cursor_pos
278
+ cont_chars = readline_count_cont_byte (rl .line -> buf + rl .orig_line_len , rl .line -> buf + rl .cursor_pos );
279
279
// increase hist num
280
280
rl .hist_cur += 1 ;
281
281
// set line to history
@@ -292,12 +292,8 @@ int readline_process_char(int c) {
292
292
#endif
293
293
// down arrow
294
294
if (rl .hist_cur >= 0 ) {
295
- for (char * ch = rl .line -> buf + rl .cursor_pos - 1 ; ch > rl .line -> buf + rl .orig_line_len ; ch -- ) {
296
- // printf("char: %d\n", ch);
297
- if (UTF8_IS_CONT (* ch )) {
298
- cont_chars ++ ;
299
- }
300
- }
295
+ // Check for continuation characters through the cursor_pos
296
+ cont_chars = readline_count_cont_byte (rl .line -> buf + rl .orig_line_len , rl .line -> buf + rl .cursor_pos );
301
297
// decrease hist num
302
298
rl .hist_cur -= 1 ;
303
299
// set line to history
@@ -321,7 +317,6 @@ int readline_process_char(int c) {
321
317
while (UTF8_IS_CONT (rl .line -> buf [rl .cursor_pos + redraw_step_forward ]) &&
322
318
rl .cursor_pos + redraw_step_forward < rl .line -> len ) {
323
319
redraw_step_forward ++ ;
324
- cont_chars ++ ;
325
320
}
326
321
}
327
322
} else if (c == 'D' ) {
@@ -332,8 +327,7 @@ int readline_process_char(int c) {
332
327
if (rl .cursor_pos > rl .orig_line_len ) {
333
328
redraw_step_back = 1 ;
334
329
// Check if we have moved into a UTF-8 continuation byte
335
- while (UTF8_IS_CONT (rl .line -> buf [rl .cursor_pos - redraw_step_back ]) &&
336
- rl .cursor_pos - redraw_step_back > rl .orig_line_len ) {
330
+ while (UTF8_IS_CONT (rl .line -> buf [rl .cursor_pos - redraw_step_back ])) {
337
331
redraw_step_back ++ ;
338
332
cont_chars ++ ;
339
333
}
@@ -352,21 +346,9 @@ int readline_process_char(int c) {
352
346
if (c == '~' ) {
353
347
if (rl .escape_seq_buf [0 ] == '1' || rl .escape_seq_buf [0 ] == '7' ) {
354
348
home_key :
355
- for (char * ch = rl .line -> buf + rl .cursor_pos - 1 ; ch > rl .line -> buf + rl .orig_line_len ; ch -- ) {
356
- // printf("char: %d\n", ch);
357
- if (UTF8_IS_CONT (* ch )) {
358
- cont_chars ++ ;
359
- }
360
- }
361
349
redraw_step_back = rl .cursor_pos - rl .orig_line_len ;
362
350
} else if (rl .escape_seq_buf [0 ] == '4' || rl .escape_seq_buf [0 ] == '8' ) {
363
351
end_key :
364
- for (char * ch = rl .line -> buf + rl .cursor_pos - 1 ; ch > rl .line -> buf + rl .orig_line_len ; ch -- ) {
365
- // printf("char: %d\n", ch);
366
- if (UTF8_IS_CONT (* ch )) {
367
- cont_chars ++ ;
368
- }
369
- }
370
352
redraw_step_forward = rl .line -> len - rl .cursor_pos ;
371
353
} else if (rl .escape_seq_buf [0 ] == '3' ) {
372
354
// delete
@@ -408,20 +390,8 @@ int readline_process_char(int c) {
408
390
// erase old chars
409
391
mp_hal_erase_line_from_cursor (last_line_len - rl .cursor_pos );
410
392
}
411
- // Check if we have moved into a UTF-8 continuation byte
412
- // while (rl.cursor_pos+redraw_step_forward < rl.line->len &&
413
- // UTF8_IS_CONT(rl.line->buf[rl.cursor_pos]) && rl.cursor_pos > 0) {
414
- // rl.cursor_pos--;
415
- // redraw_step_forward++;
416
- // }
417
-
418
- cont_chars = 0 ;
419
- for (char * ch = rl .line -> buf + rl .cursor_pos + redraw_step_forward ; ch < rl .line -> buf + rl .line -> len ; ch ++ ) {
420
- // printf("char: %d\n", ch);
421
- if (UTF8_IS_CONT (* ch )) {
422
- cont_chars ++ ;
423
- }
424
- }
393
+ // Check for continuation characters from the new cursor_pos to the EOL
394
+ cont_chars = readline_count_cont_byte (rl .line -> buf + rl .cursor_pos + redraw_step_forward , rl .line -> buf + rl .line -> len );
425
395
// draw new chars
426
396
mp_hal_stdout_tx_strn (rl .line -> buf + rl .cursor_pos , rl .line -> len - rl .cursor_pos );
427
397
// move cursor forward if needed (already moved forward by length of line, so move it back)
0 commit comments