mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
fix(grid): handle clearing half a double-width char (#27023)
This commit is contained in:
parent
7ed6966023
commit
9c202b9392
@ -655,6 +655,7 @@ void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int col, int endcol
|
|||||||
// two-cell character in the same grid, truncate that into a '>'.
|
// two-cell character in the same grid, truncate that into a '>'.
|
||||||
if (col > 0 && grid->chars[off_to + (size_t)col] == 0) {
|
if (col > 0 && grid->chars[off_to + (size_t)col] == 0) {
|
||||||
linebuf_char[col - 1] = schar_from_ascii('>');
|
linebuf_char[col - 1] = schar_from_ascii('>');
|
||||||
|
linebuf_attr[col - 1] = grid->attrs[off_to + (size_t)col - 1];
|
||||||
col--;
|
col--;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -676,7 +677,7 @@ void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int col, int endcol
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
redraw_next = grid_char_needs_redraw(grid, col, (size_t)col + off_to, endcol - col);
|
redraw_next = grid_char_needs_redraw(grid, col, off_to + (size_t)col, endcol - col);
|
||||||
|
|
||||||
int start_dirty = -1;
|
int start_dirty = -1;
|
||||||
int end_dirty = 0;
|
int end_dirty = 0;
|
||||||
@ -688,7 +689,7 @@ void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int col, int endcol
|
|||||||
char_cells = 2;
|
char_cells = 2;
|
||||||
}
|
}
|
||||||
bool redraw_this = redraw_next; // Does character need redraw?
|
bool redraw_this = redraw_next; // Does character need redraw?
|
||||||
size_t off = (size_t)col + off_to;
|
size_t off = off_to + (size_t)col;
|
||||||
redraw_next = grid_char_needs_redraw(grid, col + char_cells,
|
redraw_next = grid_char_needs_redraw(grid, col + char_cells,
|
||||||
off + (size_t)char_cells,
|
off + (size_t)char_cells,
|
||||||
endcol - col - char_cells);
|
endcol - col - char_cells);
|
||||||
@ -732,16 +733,22 @@ void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int col, int endcol
|
|||||||
if (clear_next) {
|
if (clear_next) {
|
||||||
// Clear the second half of a double-wide character of which the left
|
// Clear the second half of a double-wide character of which the left
|
||||||
// half was overwritten with a single-wide character.
|
// half was overwritten with a single-wide character.
|
||||||
grid->chars[(size_t)col + off_to] = schar_from_ascii(' ');
|
grid->chars[off_to + (size_t)col] = schar_from_ascii(' ');
|
||||||
end_dirty++;
|
end_dirty++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// When clearing the left half of a double-wide char also clear the right half.
|
||||||
|
if (off_to + (size_t)clear_width < max_off_to
|
||||||
|
&& grid->chars[off_to + (size_t)clear_width] == 0) {
|
||||||
|
clear_width++;
|
||||||
|
}
|
||||||
|
|
||||||
int clear_dirty_start = -1, clear_end = -1;
|
int clear_dirty_start = -1, clear_end = -1;
|
||||||
// blank out the rest of the line
|
// blank out the rest of the line
|
||||||
// TODO(bfredl): we could cache winline widths
|
// TODO(bfredl): we could cache winline widths
|
||||||
col = clear_start;
|
col = clear_start;
|
||||||
while (col < clear_width) {
|
while (col < clear_width) {
|
||||||
size_t off = (size_t)col + off_to;
|
size_t off = off_to + (size_t)col;
|
||||||
if (grid->chars[off] != schar_from_ascii(' ')
|
if (grid->chars[off] != schar_from_ascii(' ')
|
||||||
|| grid->attrs[off] != bg_attr
|
|| grid->attrs[off] != bg_attr
|
||||||
|| rdb_flags & RDB_NODELTA) {
|
|| rdb_flags & RDB_NODELTA) {
|
||||||
|
@ -22,6 +22,8 @@ describe('multibyte rendering', function()
|
|||||||
[3] = { background = Screen.colors.LightMagenta },
|
[3] = { background = Screen.colors.LightMagenta },
|
||||||
[4] = { bold = true },
|
[4] = { bold = true },
|
||||||
[5] = { foreground = Screen.colors.Blue },
|
[5] = { foreground = Screen.colors.Blue },
|
||||||
|
[6] = { reverse = true, bold = true },
|
||||||
|
[7] = { reverse = true },
|
||||||
})
|
})
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@ -84,7 +86,7 @@ describe('multibyte rendering', function()
|
|||||||
{4:-- INSERT --} |
|
{4:-- INSERT --} |
|
||||||
]])
|
]])
|
||||||
|
|
||||||
-- check double-with char is temporarily hidden when overlapped
|
-- check double-width char is temporarily hidden when overlapped
|
||||||
fn.complete(4, { 'xx', 'yy' })
|
fn.complete(4, { 'xx', 'yy' })
|
||||||
screen:expect([[
|
screen:expect([[
|
||||||
ab xx^ |
|
ab xx^ |
|
||||||
@ -104,6 +106,34 @@ describe('multibyte rendering', function()
|
|||||||
]])
|
]])
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('no stray chars when splitting left of window with double-width chars', function()
|
||||||
|
api.nvim_buf_set_lines(0, 0, -1, true, {
|
||||||
|
('口'):rep(16),
|
||||||
|
'a' .. ('口'):rep(16),
|
||||||
|
'aa' .. ('口'):rep(16),
|
||||||
|
'aaa' .. ('口'):rep(16),
|
||||||
|
'aaaa' .. ('口'):rep(16),
|
||||||
|
})
|
||||||
|
screen:expect([[
|
||||||
|
^口口口口口口口口口口口口口口口口 |
|
||||||
|
a口口口口口口口口口口口口口口口口 |
|
||||||
|
aa口口口口口口口口口口口口口口口口 |
|
||||||
|
aaa口口口口口口口口口口口口口口口口 |
|
||||||
|
aaaa口口口口口口口口口口口口口口口口 |
|
||||||
|
|
|
||||||
|
]])
|
||||||
|
|
||||||
|
command('20vnew')
|
||||||
|
screen:expect([[
|
||||||
|
^ │口口口口口口口口口口口口口口口口 |
|
||||||
|
{1:~ }│a口口口口口口口口口口口口口口口口 |
|
||||||
|
{1:~ }│aa口口口口口口口口口口口口口口口口 |
|
||||||
|
{1:~ }│aaa口口口口口口口口口口口口口口口口 |
|
||||||
|
{6:[No Name] }{7:[No Name] [+] }|
|
||||||
|
|
|
||||||
|
]])
|
||||||
|
end)
|
||||||
|
|
||||||
it('0xffff is shown as 4 hex digits', function()
|
it('0xffff is shown as 4 hex digits', function()
|
||||||
command([[call setline(1, "\uFFFF!!!")]])
|
command([[call setline(1, "\uFFFF!!!")]])
|
||||||
feed('$')
|
feed('$')
|
||||||
|
Loading…
Reference in New Issue
Block a user