fix(pum): info float width grows on reselect with 'linebreak' #38680

Problem: win_linetabsize() includes wrap overhead from 'linebreak'
based on current window width, but the result sizes the window,
causing a feedback loop.

Solution: Temporarily set w_view_width to Columns before measuring.
This commit is contained in:
glepnir
2026-04-12 23:42:27 +08:00
committed by GitHub
parent 1033739b60
commit fcdb148437
2 changed files with 13 additions and 4 deletions

View File

@@ -941,11 +941,16 @@ static void pum_preview_set_text(win_T *win, char *info, linenr_T *lnum, int *ma
*next = NUL; // Temporarily replace the newline with a string terminator
}
// Only skip if this is an empty line AND it's the last line
if (*curr == '\0' && !next) {
if (*curr == NUL && !next) {
break;
}
*max_width = MAX(*max_width, win_linetabsize(win, 0, curr, MAXCOL));
// Temporarily disable 'wrap' to avoid 'showbreak/linebreak'
// inflating the result when the window is narrow.
bool save_wrap = win->w_p_wrap;
win->w_p_wrap = false;
int line_width = win_linetabsize(win, 0, curr, MAXCOL);
win->w_p_wrap = save_wrap;
*max_width = MAX(*max_width, line_width);
ADD(replacement, STRING_OBJ(cstr_to_string(curr)));
(*lnum)++;

View File

@@ -2142,15 +2142,19 @@ describe('builtin popupmenu', function()
eq(1, n.eval([[len(uniq(copy(g:bufnrs))) == 1]]))
end)
it('handles tabs in info width calculation', function()
it('handles tabs and "linebreak" in info width calculation', function()
screen:try_resize(50, 11)
command([[
set linebreak
set cot+=menuone
let g:list = [#{word: 'class', info: "\tClassName() = default;"}]
]])
feed('S<C-x><C-o>')
local info = fn.complete_info()
eq(30, api.nvim_win_get_width(info.preview_winid))
feed('<C-N><C-P>')
info = fn.complete_info()
eq(30, api.nvim_win_get_width(info.preview_winid))
feed('<ESC>')
exec([[
setlocal tabstop=1