From 87ba1d7465e421f2a42a4c2b1403d91da908d30e Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 8 Jul 2025 06:37:30 +0800 Subject: [PATCH] vim-patch:9.1.1521: completion: pum does not reset scroll pos on reopen with 'noselect' (#34836) Problem: When 'wildmode' is set to include "noselect", the popup menu (pum) incorrectly retained its scroll position when reopened. This meant that after scrolling down through the menu with ``, reopening the menu (e.g., by retyping the command and triggering completion again) would show the menu starting from the previously scrolled position, rather than from the top. This could confuse users, as the first visible item would not be the first actual match in the list. Solution: Ensure that the popup menu resets its scroll position to the top when reopened (Girish Palya). closes: vim/vim#17673 https://github.com/vim/vim/commit/0cd7f3536bde47cf9693090b839abf88c7f019c8 Co-authored-by: Girish Palya --- src/nvim/cmdexpand.c | 1 + test/functional/ui/popupmenu_spec.lua | 43 +++++++++++++++++++++++++++ test/old/testdir/test_cmdline.vim | 31 +++++++++++++++++++ 3 files changed, 75 insertions(+) diff --git a/src/nvim/cmdexpand.c b/src/nvim/cmdexpand.c index 5c3b17b903..f6e1a61db7 100644 --- a/src/nvim/cmdexpand.c +++ b/src/nvim/cmdexpand.c @@ -378,6 +378,7 @@ static int cmdline_pum_create(CmdlineInfo *ccline, expand_T *xp, char **matches, // no default selection compl_selected = -1; + pum_clear(); cmdline_pum_display(true); return EXPAND_OK; diff --git a/test/functional/ui/popupmenu_spec.lua b/test/functional/ui/popupmenu_spec.lua index 46f4f79789..0e70ec7857 100644 --- a/test/functional/ui/popupmenu_spec.lua +++ b/test/functional/ui/popupmenu_spec.lua @@ -5494,6 +5494,49 @@ describe('builtin popupmenu', function() ]]) end) + -- oldtest: Test_pum_scroll_noselect() + it('cmdline pum does not retain scroll position with "noselect"', function() + screen:try_resize(32, 10) + exec([[ + command! -nargs=* -complete=customlist,TestFn TestCmd echo + func TestFn(a, b, c) + return map(range(1, 50), 'printf("a%d", v:val)') + endfunc + set wildmode=noselect,full + set wildoptions=pum + set wildmenu + set noruler + ]]) + + feed(':TestCmd ' .. (''):rep(20)) + screen:expect([[ + {n: a15 }{s: } | + {1:~ }{n: a16 }{s: }{1: }| + {1:~ }{n: a17 }{s: }{1: }| + {1:~ }{n: a18 }{c: }{1: }| + {1:~ }{n: a19 }{s: }{1: }| + {1:~ }{s: a20 }{1: }| + {1:~ }{n: a21 }{s: }{1: }| + {1:~ }{n: a22 }{s: }{1: }| + {1:~ }{n: a23 }{s: }{1: }| + :TestCmd a20^ | + ]]) + + feed(':TestCmd ') + screen:expect([[ + {n: a1 }{c: } | + {1:~ }{n: a2 }{s: }{1: }| + {1:~ }{n: a3 }{s: }{1: }| + {1:~ }{n: a4 }{s: }{1: }| + {1:~ }{n: a5 }{s: }{1: }| + {1:~ }{n: a6 }{s: }{1: }| + {1:~ }{n: a7 }{s: }{1: }| + {1:~ }{n: a8 }{s: }{1: }| + {1:~ }{n: a9 }{s: }{1: }| + :TestCmd ^ | + ]]) + end) + it( 'cascading highlights for matched text (PmenuMatch, PmenuMatchSel) in cmdline pum', function() diff --git a/test/old/testdir/test_cmdline.vim b/test/old/testdir/test_cmdline.vim index 075bdae8d1..2611b32fef 100644 --- a/test/old/testdir/test_cmdline.vim +++ b/test/old/testdir/test_cmdline.vim @@ -4287,4 +4287,35 @@ func Test_cd_bslash_completion_windows() let &shellslash = save_shellslash endfunc +" With 'noselect' in 'wildmode', ensure that the popup menu (pum) does not retain +" its scroll position after reopening. The menu should open showing the top items, +" regardless of previous scrolling. +func Test_pum_scroll_noselect() + CheckScreendump + + let lines =<< trim [SCRIPT] + command! -nargs=* -complete=customlist,TestFn TestCmd echo + func TestFn(a, b, c) + return map(range(1, 50), 'printf("a%d", v:val)') + endfunc + set wildmode=noselect,full + set wildoptions=pum + set wildmenu + set noruler + [SCRIPT] + call writefile(lines, 'XTest_pum_scroll', 'D') + let buf = RunVimInTerminal('-S XTest_pum_scroll', {'rows': 10}) + + call term_sendkeys(buf, ":TestCmd \" . repeat("\", 20)) + call TermWait(buf, 50) + call VerifyScreenDump(buf, 'Test_pum_scroll_noselect_1', {}) + + call term_sendkeys(buf, "\:TestCmd \") + call TermWait(buf, 50) + call VerifyScreenDump(buf, 'Test_pum_scroll_noselect_2', {}) + + call term_sendkeys(buf, "\") + call StopVimInTerminal(buf) +endfunc + " vim: shiftwidth=2 sts=2 expandtab