fix(pum): text overflows into border on truncation (#37438)

Problem:
When text is too long, it overflows into the border. This happens because
grid_line_maxcol includes border columns, so grid_line_puts can write
there.

Solution:
Truncate string to available width when need_fcs_trunc is set.
This commit is contained in:
glepnir
2026-01-18 16:55:30 +08:00
committed by GitHub
parent 41068c77aa
commit 5a65321684
2 changed files with 56 additions and 0 deletions

View File

@@ -817,6 +817,23 @@ void pum_redraw(void)
if (width_limit - totwidth < cells + pad) {
need_fcs_trunc = true;
}
if (need_fcs_trunc) {
int available_cells = width_limit - totwidth;
// Find the truncation point by counting display cells
char *p_end = st;
int displayed = 0;
while (*p_end != NUL) {
int char_cells = utf_ptr2cells(p_end);
if (displayed + char_cells > available_cells) {
break;
}
displayed += char_cells;
MB_PTR_ADV(p_end);
}
*p_end = NUL;
cells = displayed;
width = displayed;
}
if (attrs == NULL) {
grid_line_puts(grid_col, st, -1, attr);

View File

@@ -9405,6 +9405,45 @@ describe('builtin popupmenu', function()
assert_alive()
eq({ 4, 1 }, { #fn.complete_info({ 'items' }).items, fn.pumvisible() })
end)
it("works with 'pummaxwidth' #test", function()
exec([[
set pummaxwidth=10
set cot+=menuone
let g:list = [#{word: repeat('fo', 10)}]
]])
feed('S<C-x><C-o>')
if multigrid then
screen:expect({
grid = [[
## grid 1
[2:------------------------------]|*10
[3:------------------------------]|
## grid 2
fofofofofofofofofofo^ |
{1:~ }|*9
## grid 3
{5:-- The only match} |
## grid 4
╭──────────╮|
│{12:fofofofof>}│|
╰──────────╯|
]],
float_pos = {
[4] = { -1, 'NW', 2, 1, 0, false, 100, 1, 1, 0 },
},
})
else
screen:expect([[
fofofofofofofofofofo^ |
╭──────────╮{1: }|
│{12:fofofofof>}│{1: }|
╰──────────╯{1: }|
{1:~ }|*6
{5:-- The only match} |
]])
end
end)
end)
end