1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

term.ui: add support for multi byte/UTF-8 events (#13274)

This commit is contained in:
Larpon 2022-01-25 13:46:48 +01:00 committed by GitHub
parent ca1f675dba
commit 28ddd8440a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 53 additions and 3 deletions

View File

@ -6,6 +6,9 @@ module ui
struct ExtraContext {
mut:
read_buf []byte
// read_all_bytes causes all the raw bytes to be read as one event unit.
// This is cruicial for UTF-8 support since Unicode codepoints can span several bytes.
read_all_bytes bool = true
}
const ctx_ptr = &Context(0)

View File

@ -258,8 +258,14 @@ fn (mut ctx Context) parse_events() {
event = e
ctx.shift(len)
} else {
event = single_char(ctx.read_buf.bytestr())
ctx.shift(1)
if ctx.read_all_bytes {
e, len := multi_char(ctx.read_buf.bytestr())
event = e
ctx.shift(len)
} else {
event = single_char(ctx.read_buf.bytestr())
ctx.shift(1)
}
}
if event != 0 {
ctx.event(event)
@ -271,6 +277,47 @@ fn (mut ctx Context) parse_events() {
fn single_char(buf string) &Event {
ch := buf[0]
mut event := &Event{
typ: .key_down
ascii: ch
code: KeyCode(ch)
utf8: ch.ascii_str()
}
match ch {
// special handling for `ctrl + letter`
// TODO: Fix assoc in V and remove this workaround :/
// 1 ... 26 { event = Event{ ...event, code: KeyCode(96 | ch), modifiers: .ctrl } }
// 65 ... 90 { event = Event{ ...event, code: KeyCode(32 | ch), modifiers: .shift } }
// The bit `or`s here are really just `+`'s, just written in this way for a tiny performance improvement
// don't treat tab, enter as ctrl+i, ctrl+j
1...8, 11...26 {
event = &Event{
typ: event.typ
ascii: event.ascii
utf8: event.utf8
code: KeyCode(96 | ch)
modifiers: .ctrl
}
}
65...90 {
event = &Event{
typ: event.typ
ascii: event.ascii
utf8: event.utf8
code: KeyCode(32 | ch)
modifiers: .shift
}
}
else {}
}
return event
}
fn multi_char(buf string) (&Event, int) {
ch := buf[0]
mut event := &Event{
typ: .key_down
ascii: ch
@ -306,7 +353,7 @@ fn single_char(buf string) &Event {
else {}
}
return event
return event, buf.len
}
// Gets an entire, independent escape sequence from the buffer