From fcdb1484376cb5079387f2a7d475bdd035b7fccb Mon Sep 17 00:00:00 2001 From: glepnir Date: Sun, 12 Apr 2026 23:42:27 +0800 Subject: [PATCH] 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. --- src/nvim/popupmenu.c | 11 ++++++++--- test/functional/ui/popupmenu_spec.lua | 6 +++++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/nvim/popupmenu.c b/src/nvim/popupmenu.c index 763735a7d0..bf080136c2 100644 --- a/src/nvim/popupmenu.c +++ b/src/nvim/popupmenu.c @@ -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)++; diff --git a/test/functional/ui/popupmenu_spec.lua b/test/functional/ui/popupmenu_spec.lua index 3f700b40e5..4b69fb62ff 100644 --- a/test/functional/ui/popupmenu_spec.lua +++ b/test/functional/ui/popupmenu_spec.lua @@ -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') local info = fn.complete_info() eq(30, api.nvim_win_get_width(info.preview_winid)) + feed('') + info = fn.complete_info() + eq(30, api.nvim_win_get_width(info.preview_winid)) feed('') exec([[ setlocal tabstop=1