examples: fix navigating unicode text in text_editor (#13286)
parent
01c72d44e8
commit
65a97a9fbe
|
@ -7,8 +7,36 @@ import os
|
|||
import math
|
||||
import term.ui as tui
|
||||
import encoding.utf8
|
||||
import encoding.utf8.east_asian
|
||||
|
||||
const rune_digits = [`0`, `1`, `2`, `3`, `4`, `5`, `6`, `7`, `8`, `9`]
|
||||
const (
|
||||
rune_digits = [`0`, `1`, `2`, `3`, `4`, `5`, `6`, `7`, `8`, `9`]
|
||||
|
||||
zero_width_unicode = [
|
||||
`\u034f`, // U+034F COMBINING GRAPHEME JOINER
|
||||
`\u061c`, // U+061C ARABIC LETTER MARK
|
||||
`\u17b4`, // U+17B4 KHMER VOWEL INHERENT AQ
|
||||
`\u17b5`, // U+17B5 KHMER VOWEL INHERENT AA
|
||||
`\u200a`, // U+200A HAIR SPACE
|
||||
`\u200b`, // U+200B ZERO WIDTH SPACE
|
||||
`\u200c`, // U+200C ZERO WIDTH NON-JOINER
|
||||
`\u200d`, // U+200D ZERO WIDTH JOINER
|
||||
`\u200e`, // U+200E LEFT-TO-RIGHT MARK
|
||||
`\u200f`, // U+200F RIGHT-TO-LEFT MARK
|
||||
`\u2060`, // U+2060 WORD JOINER
|
||||
`\u2061`, // U+2061 FUNCTION APPLICATION
|
||||
`\u2062`, // U+2062 INVISIBLE TIMES
|
||||
`\u2063`, // U+2063 INVISIBLE SEPARATOR
|
||||
`\u2064`, // U+2064 INVISIBLE PLUS
|
||||
`\u206a`, // U+206A INHIBIT SYMMETRIC SWAPPING
|
||||
`\u206b`, // U+206B ACTIVATE SYMMETRIC SWAPPING
|
||||
`\u206c`, // U+206C INHIBIT ARABIC FORM SHAPING
|
||||
`\u206d`, // U+206D ACTIVATE ARABIC FORM SHAPING
|
||||
`\u206e`, // U+206E NATIONAL DIGIT SHAPES
|
||||
`\u206f`, // U+206F NOMINAL DIGIT SHAPES
|
||||
`\ufeff`, // U+FEFF ZERO WIDTH NO-BREAK SPACE
|
||||
]
|
||||
)
|
||||
|
||||
enum Movement {
|
||||
up
|
||||
|
@ -170,6 +198,14 @@ fn (b Buffer) cur_line() string {
|
|||
return b.line(b.cursor.pos_y)
|
||||
}
|
||||
|
||||
fn (b Buffer) cur_slice() string {
|
||||
line := b.line(b.cursor.pos_y).runes()
|
||||
if b.cursor.pos_x == 0 || b.cursor.pos_x > line.len {
|
||||
return ''
|
||||
}
|
||||
return line[..b.cursor.pos_x].string()
|
||||
}
|
||||
|
||||
fn (b Buffer) cursor_index() int {
|
||||
mut i := 0
|
||||
for y, line in b.lines {
|
||||
|
@ -501,7 +537,17 @@ fn frame(x voidptr) {
|
|||
view := ed.view(a.viewport, scroll_limit + a.viewport)
|
||||
a.tui.draw_text(0, 0, view.raw)
|
||||
a.footer()
|
||||
a.tui.set_cursor_position(view.cursor.pos_x + 1, ed.cursor.pos_y + 1 - a.viewport)
|
||||
|
||||
// Unicode: Handle correct mapping of cursor X position in terminal.
|
||||
mut ch_x := view.cursor.pos_x
|
||||
mut sl := ed.cur_slice().replace('\t', ' '.repeat(ed.tab_width))
|
||||
if sl.len > 0 {
|
||||
// Strip out any zero-width codepoints.
|
||||
sl = sl.runes().filter(it !in zero_width_unicode).string()
|
||||
ch_x = east_asian.display_width(sl, 1)
|
||||
}
|
||||
|
||||
a.tui.set_cursor_position(ch_x + 1, ed.cursor.pos_y + 1 - a.viewport)
|
||||
a.tui.flush()
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue