mirror of
https://github.com/neovim/neovim.git
synced 2026-03-31 12:52:13 +00:00
fix(terminal): handle split composing chars at right edge (#37694)
Problem: Recombining composing chars in terminal doesn't work at right edge. Solution: Check for the case where printing the previous char didn't advance the cursor. Reset at_phantom when returning to combine_pos.
This commit is contained in:
@@ -342,13 +342,15 @@ static int on_text(const char bytes[], size_t len, void *user)
|
||||
|
||||
// See if the cursor has moved since
|
||||
if (state->pos.row == state->combine_pos.row
|
||||
&& state->pos.col == state->combine_pos.col + state->combine_width) {
|
||||
&& state->pos.col >= state->combine_pos.col
|
||||
&& state->pos.col <= state->combine_pos.col + state->combine_width) {
|
||||
// This is a combining char. that needs to be merged with the previous glyph output
|
||||
if (utf_iscomposing((int)state->grapheme_last, (int)codepoints[i], &state->grapheme_state)) {
|
||||
// Find where we need to append these combining chars
|
||||
grapheme_len = state->grapheme_len;
|
||||
grapheme_state = state->grapheme_state;
|
||||
state->pos.col = state->combine_pos.col;
|
||||
state->at_phantom = 0;
|
||||
recombine = true;
|
||||
} else {
|
||||
DEBUG_LOG("libvterm: TODO: Skip over split char+combining\n");
|
||||
|
||||
@@ -758,7 +758,7 @@ describe(':terminal buffer', function()
|
||||
end)
|
||||
|
||||
it('handles split UTF-8 sequences #16245', function()
|
||||
local screen = Screen.new(50, 7)
|
||||
local screen = Screen.new(50, 10)
|
||||
fn.jobstart({ testprg('shell-test'), 'UTF-8' }, { term = true })
|
||||
screen:expect([[
|
||||
^å |
|
||||
@@ -766,7 +766,24 @@ describe(':terminal buffer', function()
|
||||
1: å̲ |
|
||||
2: å̲ |
|
||||
3: å̲ |
|
||||
|*2
|
||||
|
|
||||
[Process exited 0] |
|
||||
|*3
|
||||
]])
|
||||
-- Test with Unicode char at right edge using a 4-wide terminal
|
||||
command('bwipe! | set laststatus=0 | 4vnew')
|
||||
fn.jobstart({ testprg('shell-test'), 'UTF-8' }, { term = true })
|
||||
screen:expect([[
|
||||
^å │ |
|
||||
ref:│{1:~ }|
|
||||
å̲ │{1:~ }|
|
||||
1: å̲│{1:~ }|
|
||||
2: å̲│{1:~ }|
|
||||
3: å̲│{1:~ }|
|
||||
│{1:~ }|
|
||||
[Pro│{1:~ }|
|
||||
cess│{1:~ }|
|
||||
|
|
||||
]])
|
||||
end)
|
||||
|
||||
|
||||
@@ -992,6 +992,7 @@ describe('vterm', function()
|
||||
push('e' .. string.rep('\xCC\x81', 20), vt)
|
||||
expect('putglyph 65,301,301,301,301,301,301,301,301,301,301,301,301,301,301 1 0,0') -- and nothing more
|
||||
|
||||
-- Combining across buffers multiple times
|
||||
reset(state, nil)
|
||||
push('e', vt)
|
||||
expect('putglyph 65 1 0,0')
|
||||
@@ -1000,6 +1001,32 @@ describe('vterm', function()
|
||||
push('\xCC\x82', vt)
|
||||
expect('putglyph 65,301,302 1 0,0')
|
||||
|
||||
-- Combining across buffers at right edge
|
||||
reset(state, nil)
|
||||
push('\x1b[5;80H', vt)
|
||||
push('e', vt)
|
||||
expect('putglyph 65 1 4,79')
|
||||
push('\xCC\x81', vt)
|
||||
expect('putglyph 65,301 1 4,79')
|
||||
push('\xCC\x82Z', vt)
|
||||
expect('putglyph 65,301,302 1 4,79\nputglyph 5a 1 5,0')
|
||||
|
||||
-- Combining regional indicators
|
||||
reset(state, nil)
|
||||
push('\x1b[5;77H', vt)
|
||||
push('🇦', vt)
|
||||
expect('putglyph 1f1e6 2 4,76')
|
||||
push('🇩', vt)
|
||||
expect('putglyph 1f1e6,1f1e9 2 4,76')
|
||||
push('🇱', vt)
|
||||
expect('putglyph 1f1f1 2 4,78')
|
||||
push('🇮', vt)
|
||||
expect('putglyph 1f1f1,1f1ee 2 4,78')
|
||||
push('🇲', vt)
|
||||
expect('putglyph 1f1f2 2 5,0')
|
||||
push('🇨', vt)
|
||||
expect('putglyph 1f1f2,1f1e8 2 5,0')
|
||||
|
||||
-- emoji with ZWJ and variant selectors, as one chunk
|
||||
reset(state, nil)
|
||||
push('🏳️🌈🏳️⚧️🏴☠️', vt)
|
||||
|
||||
Reference in New Issue
Block a user