fix(pum): keep info window aligned with pum when above #38251

Problem:
When `pum_above` is set, the info window uses `anchor=SW`. Updating the
info window height during `CompleteChanged` causes its top edge to shift,
so it no longer aligns with the top of the pum.

Solution:
Use `NW` as the anchor even when `pum_above` is true so the info window
remains aligned with `pum_row`.
This commit is contained in:
glepnir
2026-03-12 17:48:14 +08:00
committed by GitHub
parent c5146362d8
commit d87972f920
2 changed files with 53 additions and 8 deletions

View File

@@ -1003,12 +1003,11 @@ static bool pum_adjust_info_position(win_T *wp, int width)
wp->w_config.width = max_extra;
wp->w_config.col = place_in_right ? col - 1 : pum_col - wp->w_config.width - 1;
}
// when pum_above is SW otherwise is NW
wp->w_config.anchor = pum_above ? kFloatAnchorSouth : 0;
wp->w_config.anchor = 0; // NW: align top of info window with top of pum
linenr_T count = wp->w_buffer->b_ml.ml_line_count;
wp->w_view_width = wp->w_config.width;
wp->w_config.height = plines_m_win(wp, wp->w_topline, count, Rows);
wp->w_config.row = pum_above ? pum_row + wp->w_config.height : pum_row;
wp->w_config.row = pum_row;
wp->w_config.hide = false;
win_config_float(wp, wp->w_config);
return true;

View File

@@ -1744,6 +1744,7 @@ describe('builtin popupmenu', function()
exec([[
let g:list = [#{word: "one", info: "1info"}, #{word: "two", info: "2info"}, #{word: "looooooooooooooong"}]
let g:bufnrs = []
let g:reduce_info_height = 0
funct Omni_test(findstart, base)
if a:findstart
return col(".") - 1
@@ -1763,11 +1764,15 @@ describe('builtin popupmenu', function()
endfunc
funct TsHl()
let comp_info = complete_info(['selected'])
if get(comp_info, 'preview_bufnr', 0) > 0
call v:lua.vim.treesitter.start(comp_info['preview_bufnr'], 'markdown')
endif
if comp_info['selected'] == 0
call nvim__complete_set(comp_info['selected'], {"info": "```lua\nfunction test()\n print('foo')\nend\n```"})
let windata = nvim__complete_set(comp_info['selected'], {"info": "```lua\nfunction test()\n print('foo')\nend\n```"})
call v:lua.vim.treesitter.start(windata['bufnr'], 'markdown')
if g:reduce_info_height > 0
let h = v:lua.vim.api.nvim_win_text_height(windata['winid'], {}).all
if h > 3
call v:lua.vim.api.nvim_win_set_height(windata['winid'], h - 3)
endif
endif
endif
endfunc
augroup Group
@@ -2154,7 +2159,48 @@ describe('builtin popupmenu', function()
{5:-- }{6:match 1 of 3} |
]])
end
feed('<C-E><ESC>')
end)
it('info window aligns with pum when above cursor', function()
command('let g:reduce_info_height=1 | call TestTs()')
feed('<C-E><ESC>18o<Esc>i<C-x><C-O>')
if multigrid then
screen:expect({
grid = [[
## grid 1
[2:----------------------------------------]|*10
[3:----------------------------------------]|
## grid 2
|*9
one^ |
## grid 3
{5:-- }{6:match 1 of 3} |
## grid 4
{mn:```}{102:lua}{n: }|
{102:function}{mn: }{103:test}{104:()}|
## grid 5
{12:one }|
{n:two }|
{n:looooooooooooooong }|
]],
win_pos = {
[2] = { height = 10, startcol = 0, startrow = 0, width = 40, win = 1000 },
},
float_pos = {
[5] = { -1, 'SW', 2, 9, 0, false, 100, 2, 6, 0 },
[4] = { 1001, 'NW', 1, 6, 19, false, 50, 1, 6, 19 },
},
})
else
screen:expect([[
|*6
{12:one }{mn:```}{102:lua}{n: } |
{n:two }{102:function}{mn: }{103:test}{104:()} |
{n:looooooooooooooong } |
one^ |
{5:-- }{6:match 1 of 3} |
]])
end
end)
it('avoid modified original info text', function()