examples: fix navigating unicode text in text_editor (#13286)

pull/13290/head
Larpon 2022-01-26 16:25:29 +01:00 committed by GitHub
parent 01c72d44e8
commit 65a97a9fbe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 48 additions and 2 deletions

View File

@ -7,8 +7,36 @@ import os
import math import math
import term.ui as tui import term.ui as tui
import encoding.utf8 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 { enum Movement {
up up
@ -170,6 +198,14 @@ fn (b Buffer) cur_line() string {
return b.line(b.cursor.pos_y) 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 { fn (b Buffer) cursor_index() int {
mut i := 0 mut i := 0
for y, line in b.lines { for y, line in b.lines {
@ -501,7 +537,17 @@ fn frame(x voidptr) {
view := ed.view(a.viewport, scroll_limit + a.viewport) view := ed.view(a.viewport, scroll_limit + a.viewport)
a.tui.draw_text(0, 0, view.raw) a.tui.draw_text(0, 0, view.raw)
a.footer() 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() a.tui.flush()
} }