mirror of
https://github.com/neovim/neovim.git
synced 2026-04-25 00:35:36 +00:00
fix(vterm): handle split UTF-8 after ASCII properly (#37721)
Problem: libvterm doesn't handle split UTF-8 sequence after ASCII. Solution: Only use one UTF-8 encoding state per vterm state.
This commit is contained in:
@@ -660,21 +660,6 @@ static size_t on_channel_output(RStream *stream, Channel *chan, const char *buf,
|
|||||||
bool eof, CallbackReader *reader)
|
bool eof, CallbackReader *reader)
|
||||||
{
|
{
|
||||||
if (chan->term) {
|
if (chan->term) {
|
||||||
if (count) {
|
|
||||||
const char *p = buf;
|
|
||||||
const char *end = buf + count;
|
|
||||||
while (p < end) {
|
|
||||||
// Don't pass incomplete UTF-8 sequences to libvterm. #16245
|
|
||||||
// Composing chars can be passed separately, so utf_ptr2len_len() is enough.
|
|
||||||
int clen = utf_ptr2len_len(p, (int)(end - p));
|
|
||||||
if (clen > end - p) {
|
|
||||||
count = (size_t)(p - buf);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
p += clen;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
terminal_receive(chan->term, buf, count);
|
terminal_receive(chan->term, buf, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -321,6 +321,9 @@ static int on_text(const char bytes[], size_t len, void *user)
|
|||||||
: state->vt->mode.utf8 ? &state->encoding_utf8
|
: state->vt->mode.utf8 ? &state->encoding_utf8
|
||||||
: &state->encoding[state->
|
: &state->encoding[state->
|
||||||
gr_set];
|
gr_set];
|
||||||
|
if (encoding->enc == state->encoding_utf8.enc) {
|
||||||
|
encoding = &state->encoding_utf8; // Only use one UTF-8 encoding state.
|
||||||
|
}
|
||||||
|
|
||||||
(*encoding->enc->decode)(encoding->enc, encoding->data,
|
(*encoding->enc->decode)(encoding->enc, encoding->data,
|
||||||
codepoints, &npoints, state->gsingle_set ? 1 : (int)maxpoints,
|
codepoints, &npoints, state->gsingle_set ? 1 : (int)maxpoints,
|
||||||
|
|||||||
@@ -1827,11 +1827,20 @@ putglyph 1f3f4,200d,2620,fe0f 2 0,4]])
|
|||||||
expect('putglyph 2592 1 0,1')
|
expect('putglyph 2592 1 0,1')
|
||||||
|
|
||||||
vterm.vterm_set_utf8(vt, true)
|
vterm.vterm_set_utf8(vt, true)
|
||||||
|
|
||||||
|
-- Mixed US-ASCII and UTF-8
|
||||||
-- U+0108 == c4 88
|
-- U+0108 == c4 88
|
||||||
reset(state, nil)
|
reset(state, nil)
|
||||||
push('\x1b(B', vt)
|
push('\x1b(B', vt)
|
||||||
push('AB\xc4\x88D', vt)
|
push('AB\xc4\x88D', vt)
|
||||||
expect('putglyph 41 1 0,0\nputglyph 42 1 0,1\nputglyph 108 1 0,2\nputglyph 44 1 0,3')
|
expect('putglyph 41 1 0,0\nputglyph 42 1 0,1\nputglyph 108 1 0,2\nputglyph 44 1 0,3')
|
||||||
|
|
||||||
|
-- Split UTF-8 after US-ASCII
|
||||||
|
reset(state, nil)
|
||||||
|
push('AB\xc4', vt)
|
||||||
|
expect('putglyph 41 1 0,0\nputglyph 42 1 0,1')
|
||||||
|
push('\x88D', vt)
|
||||||
|
expect('putglyph 108 1 0,2\nputglyph 44 1 0,3')
|
||||||
end)
|
end)
|
||||||
|
|
||||||
itp('15state_mode', function()
|
itp('15state_mode', function()
|
||||||
|
|||||||
Reference in New Issue
Block a user