mirror of
https://github.com/neovim/neovim.git
synced 2024-12-19 10:45:16 -07:00
fix(tui): make setcellwidths() work for non-ambiwidth chars (#28322)
This commit is contained in:
parent
a928228355
commit
4c31a1b807
@ -963,17 +963,17 @@ static void print_spaces(TUIData *tui, int width)
|
||||
}
|
||||
}
|
||||
|
||||
/// Move cursor to the position given by `row` and `col` and print the character in `cell`.
|
||||
/// This allows the grid and the host terminal to assume different widths of ambiguous-width chars.
|
||||
/// Move cursor to the position given by `row` and `col` and print the char in `cell`.
|
||||
/// Allows grid and host terminal to assume different widths of ambiguous-width chars.
|
||||
///
|
||||
/// @param is_doublewidth whether the character is double-width on the grid.
|
||||
/// If true and the character is ambiguous-width, clear two cells.
|
||||
/// @param is_doublewidth whether the char is double-width on the grid.
|
||||
/// If true and the char is ambiguous-width, clear two cells.
|
||||
static void print_cell_at_pos(TUIData *tui, int row, int col, UCell *cell, bool is_doublewidth)
|
||||
{
|
||||
UGrid *grid = &tui->grid;
|
||||
|
||||
if (grid->row == -1 && cell->data == NUL) {
|
||||
// If cursor needs to repositioned and there is nothing to print, don't move cursor.
|
||||
// If cursor needs repositioning and there is nothing to print, don't move cursor.
|
||||
return;
|
||||
}
|
||||
|
||||
@ -981,10 +981,14 @@ static void print_cell_at_pos(TUIData *tui, int row, int col, UCell *cell, bool
|
||||
|
||||
char buf[MAX_SCHAR_SIZE];
|
||||
schar_get(buf, cell->data);
|
||||
bool is_ambiwidth = utf_ambiguous_width(utf_ptr2char(buf));
|
||||
if (is_ambiwidth && is_doublewidth) {
|
||||
int c = utf_ptr2char(buf);
|
||||
bool is_ambiwidth = utf_ambiguous_width(c);
|
||||
if (is_doublewidth && (is_ambiwidth || utf_char2cells(c) == 1)) {
|
||||
// If the server used setcellwidths() to treat a single-width char as double-width,
|
||||
// it needs to be treated like an ambiguous-width char.
|
||||
is_ambiwidth = true;
|
||||
// Clear the two screen cells.
|
||||
// If the character is single-width in the host terminal it won't change the second cell.
|
||||
// If the char is single-width in host terminal it won't change the second cell.
|
||||
update_attrs(tui, cell->attr);
|
||||
print_spaces(tui, 2);
|
||||
cursor_goto(tui, row, col);
|
||||
@ -993,7 +997,7 @@ static void print_cell_at_pos(TUIData *tui, int row, int col, UCell *cell, bool
|
||||
print_cell(tui, buf, cell->attr);
|
||||
|
||||
if (is_ambiwidth) {
|
||||
// Force repositioning cursor after printing an ambiguous-width character.
|
||||
// Force repositioning cursor after printing an ambiguous-width char.
|
||||
grid->row = -1;
|
||||
}
|
||||
}
|
||||
|
@ -1650,7 +1650,7 @@ describe('TUI', function()
|
||||
eq(expected, rv)
|
||||
end)
|
||||
|
||||
it('allows grid to assume wider ambiguous-width characters than host terminal #19686', function()
|
||||
it('allows grid to assume wider ambiwidth chars than host terminal', function()
|
||||
child_session:request(
|
||||
'nvim_buf_set_lines',
|
||||
0,
|
||||
@ -1694,6 +1694,50 @@ describe('TUI', function()
|
||||
screen:expect(singlewidth_screen)
|
||||
end)
|
||||
|
||||
it('allows grid to assume wider non-ambiwidth chars than host terminal', function()
|
||||
child_session:request(
|
||||
'nvim_buf_set_lines',
|
||||
0,
|
||||
0,
|
||||
-1,
|
||||
true,
|
||||
{ ('✓'):rep(60), ('✓'):rep(60) }
|
||||
)
|
||||
child_session:request('nvim_set_option_value', 'cursorline', true, {})
|
||||
child_session:request('nvim_set_option_value', 'list', true, {})
|
||||
child_session:request('nvim_set_option_value', 'listchars', 'eol:$', { win = 0 })
|
||||
feed_data('gg')
|
||||
local singlewidth_screen = [[
|
||||
{13:✓}{12:✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓}|
|
||||
{12:✓✓✓✓✓✓✓✓✓✓}{15:$}{12: }|
|
||||
✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓✓|
|
||||
✓✓✓✓✓✓✓✓✓✓{4:$} |
|
||||
{5:[No Name] [+] }|
|
||||
|
|
||||
{3:-- TERMINAL --} |
|
||||
]]
|
||||
-- When grid assumes "✓" to be double-width but host terminal assumes it to be single-width,
|
||||
-- the second cell of "✓" is a space and the attributes of the "✓" are applied to it.
|
||||
local doublewidth_screen = [[
|
||||
{13:✓}{12: ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ }|
|
||||
{12:✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ }|
|
||||
{12:✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ }{15:$}{12: }|
|
||||
✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ {4:@@@@}|
|
||||
{5:[No Name] [+] }|
|
||||
|
|
||||
{3:-- TERMINAL --} |
|
||||
]]
|
||||
screen:expect(singlewidth_screen)
|
||||
child_session:request('nvim_set_option_value', 'ambiwidth', 'double', {})
|
||||
screen:expect_unchanged()
|
||||
child_session:request('nvim_call_function', 'setcellwidths', { { { 0x2713, 0x2713, 2 } } })
|
||||
screen:expect(doublewidth_screen)
|
||||
child_session:request('nvim_set_option_value', 'ambiwidth', 'single', {})
|
||||
screen:expect_unchanged()
|
||||
child_session:request('nvim_call_function', 'setcellwidths', { { { 0x2713, 0x2713, 1 } } })
|
||||
screen:expect(singlewidth_screen)
|
||||
end)
|
||||
|
||||
it('draws correctly when cursor_address overflows #21643', function()
|
||||
t.skip(is_os('mac'), 'FIXME: crashes/errors on macOS')
|
||||
screen:try_resize(77, 855)
|
||||
|
Loading…
Reference in New Issue
Block a user