mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
Merge pull request #16762 from zeertzjq/grid-truncate-pum-double-width
Truncate double-width character at the end of popup menu correctly
This commit is contained in:
commit
3e81c1f9b5
@ -386,7 +386,7 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed, i
|
|||||||
void pum_redraw(void)
|
void pum_redraw(void)
|
||||||
{
|
{
|
||||||
int row = 0;
|
int row = 0;
|
||||||
int col;
|
int grid_col;
|
||||||
int attr_norm = win_hl_attr(curwin, HLF_PNI);
|
int attr_norm = win_hl_attr(curwin, HLF_PNI);
|
||||||
int attr_select = win_hl_attr(curwin, HLF_PSI);
|
int attr_select = win_hl_attr(curwin, HLF_PSI);
|
||||||
int attr_scroll = win_hl_attr(curwin, HLF_PSB);
|
int attr_scroll = win_hl_attr(curwin, HLF_PSB);
|
||||||
@ -479,7 +479,7 @@ void pum_redraw(void)
|
|||||||
|
|
||||||
// Display each entry, use two spaces for a Tab.
|
// Display each entry, use two spaces for a Tab.
|
||||||
// Do this 3 times: For the main text, kind and extra info
|
// Do this 3 times: For the main text, kind and extra info
|
||||||
col = col_off;
|
grid_col = col_off;
|
||||||
totwidth = 0;
|
totwidth = 0;
|
||||||
|
|
||||||
for (round = 1; round <= 3; ++round) {
|
for (round = 1; round <= 3; ++round) {
|
||||||
@ -537,24 +537,15 @@ void pum_redraw(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
grid_puts_len(&pum_grid, rt, (int)STRLEN(rt), row,
|
grid_puts_len(&pum_grid, rt, (int)STRLEN(rt), row,
|
||||||
col - size + 1, attr);
|
grid_col - size + 1, attr);
|
||||||
xfree(rt_start);
|
xfree(rt_start);
|
||||||
xfree(st);
|
xfree(st);
|
||||||
col -= width;
|
grid_col -= width;
|
||||||
} else {
|
} else {
|
||||||
int size = (int)STRLEN(st);
|
// use grid_puts_len() to truncate the text
|
||||||
int cells = (int)mb_string2cells(st);
|
grid_puts(&pum_grid, st, row, grid_col, attr);
|
||||||
|
|
||||||
// only draw the text that fits
|
|
||||||
while (size > 0 && col + cells > pum_width + pum_col) {
|
|
||||||
size--;
|
|
||||||
size -= utf_head_off(st, st + size);
|
|
||||||
cells -= utf_ptr2cells(st + size);
|
|
||||||
}
|
|
||||||
|
|
||||||
grid_puts_len(&pum_grid, st, size, row, col, attr);
|
|
||||||
xfree(st);
|
xfree(st);
|
||||||
col += width;
|
grid_col += width;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*p != TAB) {
|
if (*p != TAB) {
|
||||||
@ -563,12 +554,12 @@ void pum_redraw(void)
|
|||||||
|
|
||||||
// Display two spaces for a Tab.
|
// Display two spaces for a Tab.
|
||||||
if (pum_rl) {
|
if (pum_rl) {
|
||||||
grid_puts_len(&pum_grid, (char_u *)" ", 2, row, col - 1,
|
grid_puts_len(&pum_grid, (char_u *)" ", 2, row, grid_col - 1,
|
||||||
attr);
|
attr);
|
||||||
col -= 2;
|
grid_col -= 2;
|
||||||
} else {
|
} else {
|
||||||
grid_puts_len(&pum_grid, (char_u *)" ", 2, row, col, attr);
|
grid_puts_len(&pum_grid, (char_u *)" ", 2, row, grid_col, attr);
|
||||||
col += 2;
|
grid_col += 2;
|
||||||
}
|
}
|
||||||
totwidth += 2;
|
totwidth += 2;
|
||||||
// start text at next char
|
// start text at next char
|
||||||
@ -599,21 +590,21 @@ void pum_redraw(void)
|
|||||||
|
|
||||||
if (pum_rl) {
|
if (pum_rl) {
|
||||||
grid_fill(&pum_grid, row, row + 1, col_off - pum_base_width - n + 1,
|
grid_fill(&pum_grid, row, row + 1, col_off - pum_base_width - n + 1,
|
||||||
col + 1, ' ', ' ', attr);
|
grid_col + 1, ' ', ' ', attr);
|
||||||
col = col_off - pum_base_width - n + 1;
|
grid_col = col_off - pum_base_width - n + 1;
|
||||||
} else {
|
} else {
|
||||||
grid_fill(&pum_grid, row, row + 1, col,
|
grid_fill(&pum_grid, row, row + 1, grid_col,
|
||||||
col_off + pum_base_width + n, ' ', ' ', attr);
|
col_off + pum_base_width + n, ' ', ' ', attr);
|
||||||
col = col_off + pum_base_width + n;
|
grid_col = col_off + pum_base_width + n;
|
||||||
}
|
}
|
||||||
totwidth = pum_base_width + n;
|
totwidth = pum_base_width + n;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pum_rl) {
|
if (pum_rl) {
|
||||||
grid_fill(&pum_grid, row, row + 1, col_off - pum_width + 1, col + 1,
|
grid_fill(&pum_grid, row, row + 1, col_off - pum_width + 1, grid_col + 1,
|
||||||
' ', ' ', attr);
|
' ', ' ', attr);
|
||||||
} else {
|
} else {
|
||||||
grid_fill(&pum_grid, row, row + 1, col, col_off + pum_width, ' ', ' ',
|
grid_fill(&pum_grid, row, row + 1, grid_col, col_off + pum_width, ' ', ' ',
|
||||||
attr);
|
attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5933,6 +5933,8 @@ void grid_puts_len(ScreenGrid *grid, char_u *text, int textlen, int row, int col
|
|||||||
// Only 1 cell left, but character requires 2 cells:
|
// Only 1 cell left, but character requires 2 cells:
|
||||||
// display a '>' in the last column to avoid wrapping. */
|
// display a '>' in the last column to avoid wrapping. */
|
||||||
c = '>';
|
c = '>';
|
||||||
|
u8c = '>';
|
||||||
|
u8cc[0] = 0;
|
||||||
mbyte_cells = 1;
|
mbyte_cells = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5963,6 +5965,13 @@ void grid_puts_len(ScreenGrid *grid, char_u *text, int textlen, int row, int col
|
|||||||
clear_next_cell = true;
|
clear_next_cell = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// When at the start of the text and overwriting the right half of a
|
||||||
|
// two-cell character in the same grid, truncate that into a '>'.
|
||||||
|
if (ptr == text && col > 0 && grid->chars[off][0] == 0) {
|
||||||
|
grid->chars[off - 1][0] = '>';
|
||||||
|
grid->chars[off - 1][1] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
schar_copy(grid->chars[off], buf);
|
schar_copy(grid->chars[off], buf);
|
||||||
grid->attrs[off] = attr;
|
grid->attrs[off] = attr;
|
||||||
if (mbyte_cells == 2) {
|
if (mbyte_cells == 2) {
|
||||||
|
@ -2213,4 +2213,134 @@ describe('builtin popupmenu', function()
|
|||||||
feed('<c-y>')
|
feed('<c-y>')
|
||||||
assert_alive()
|
assert_alive()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('truncates double-width character correctly when there is no scrollbar', function()
|
||||||
|
screen:try_resize(32,8)
|
||||||
|
command('set completeopt+=menuone,noselect')
|
||||||
|
feed('i' .. string.rep(' ', 13))
|
||||||
|
funcs.complete(14, {'哦哦哦哦哦哦哦哦哦哦'})
|
||||||
|
screen:expect([[
|
||||||
|
^ |
|
||||||
|
{1:~ }{n: 哦哦哦哦哦哦哦哦哦>}|
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
{2:-- INSERT --} |
|
||||||
|
]])
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('truncates double-width character correctly when there is scrollbar', function()
|
||||||
|
screen:try_resize(32,8)
|
||||||
|
command('set completeopt+=noselect')
|
||||||
|
command('set pumheight=4')
|
||||||
|
feed('i' .. string.rep(' ', 12))
|
||||||
|
local items = {}
|
||||||
|
for _ = 1, 8 do
|
||||||
|
table.insert(items, {word = '哦哦哦哦哦哦哦哦哦哦', equal = 1, dup = 1})
|
||||||
|
end
|
||||||
|
funcs.complete(13, items)
|
||||||
|
screen:expect([[
|
||||||
|
^ |
|
||||||
|
{1:~ }{n: 哦哦哦哦哦哦哦哦哦>}{c: }|
|
||||||
|
{1:~ }{n: 哦哦哦哦哦哦哦哦哦>}{c: }|
|
||||||
|
{1:~ }{n: 哦哦哦哦哦哦哦哦哦>}{s: }|
|
||||||
|
{1:~ }{n: 哦哦哦哦哦哦哦哦哦>}{s: }|
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
{2:-- INSERT --} |
|
||||||
|
]])
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
|
||||||
|
describe('builtin popupmenu with ui/ext_multigrid', function()
|
||||||
|
local screen
|
||||||
|
before_each(function()
|
||||||
|
clear()
|
||||||
|
screen = Screen.new(32, 20)
|
||||||
|
screen:attach({ext_multigrid=true})
|
||||||
|
screen:set_default_attr_ids({
|
||||||
|
-- popup selected item / scrollbar track
|
||||||
|
['s'] = {background = Screen.colors.WebGray},
|
||||||
|
-- popup non-selected item
|
||||||
|
['n'] = {background = Screen.colors.LightMagenta},
|
||||||
|
-- popup scrollbar knob
|
||||||
|
['c'] = {background = Screen.colors.Grey0},
|
||||||
|
[1] = {bold = true, foreground = Screen.colors.Blue},
|
||||||
|
[2] = {bold = true},
|
||||||
|
[3] = {reverse = true},
|
||||||
|
[4] = {bold = true, reverse = true},
|
||||||
|
[5] = {bold = true, foreground = Screen.colors.SeaGreen},
|
||||||
|
[6] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red},
|
||||||
|
})
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('truncates double-width character correctly when there is no scrollbar', function()
|
||||||
|
screen:try_resize(32,8)
|
||||||
|
command('set completeopt+=menuone,noselect')
|
||||||
|
feed('i' .. string.rep(' ', 13))
|
||||||
|
funcs.complete(14, {'哦哦哦哦哦哦哦哦哦哦'})
|
||||||
|
screen:expect({grid=[[
|
||||||
|
## grid 1
|
||||||
|
[2:--------------------------------]|
|
||||||
|
[2:--------------------------------]|
|
||||||
|
[2:--------------------------------]|
|
||||||
|
[2:--------------------------------]|
|
||||||
|
[2:--------------------------------]|
|
||||||
|
[2:--------------------------------]|
|
||||||
|
[2:--------------------------------]|
|
||||||
|
[3:--------------------------------]|
|
||||||
|
## grid 2
|
||||||
|
^ |
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
## grid 3
|
||||||
|
{2:-- INSERT --} |
|
||||||
|
## grid 4
|
||||||
|
{n: 哦哦哦哦哦哦哦哦哦>}|
|
||||||
|
]], float_pos={[4] = {{id = -1}, 'NW', 2, 1, 12, false, 100}}})
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('truncates double-width character correctly when there is scrollbar', function()
|
||||||
|
screen:try_resize(32,8)
|
||||||
|
command('set completeopt+=noselect')
|
||||||
|
command('set pumheight=4')
|
||||||
|
feed('i' .. string.rep(' ', 12))
|
||||||
|
local items = {}
|
||||||
|
for _ = 1, 8 do
|
||||||
|
table.insert(items, {word = '哦哦哦哦哦哦哦哦哦哦', equal = 1, dup = 1})
|
||||||
|
end
|
||||||
|
funcs.complete(13, items)
|
||||||
|
screen:expect({grid=[[
|
||||||
|
## grid 1
|
||||||
|
[2:--------------------------------]|
|
||||||
|
[2:--------------------------------]|
|
||||||
|
[2:--------------------------------]|
|
||||||
|
[2:--------------------------------]|
|
||||||
|
[2:--------------------------------]|
|
||||||
|
[2:--------------------------------]|
|
||||||
|
[2:--------------------------------]|
|
||||||
|
[3:--------------------------------]|
|
||||||
|
## grid 2
|
||||||
|
^ |
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
{1:~ }|
|
||||||
|
## grid 3
|
||||||
|
{2:-- INSERT --} |
|
||||||
|
## grid 4
|
||||||
|
{n: 哦哦哦哦哦哦哦哦哦>}{c: }|
|
||||||
|
{n: 哦哦哦哦哦哦哦哦哦>}{c: }|
|
||||||
|
{n: 哦哦哦哦哦哦哦哦哦>}{s: }|
|
||||||
|
{n: 哦哦哦哦哦哦哦哦哦>}{s: }|
|
||||||
|
]], float_pos={[4] = {{id = -1}, 'NW', 2, 1, 11, false, 100}}})
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
Loading…
Reference in New Issue
Block a user