From b4b93605aa2d577de30ae97de4ddea81df444093 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 5 May 2026 07:02:20 +0800 Subject: [PATCH] vim-patch:9.2.0439: completion: info popup not removed in cmdline mode (#39595) Problem: Info popup isn't removed when selecting an item that doesn't have "info" in cmdline completion, which is inconsistent with Insert mode behavior. Solution: Set pum_call_update_screen in cmdline mode (zeertzjq). closes: vim/vim#20128 https://github.com/vim/vim/commit/3bfffcc29054faff2dbec2d765317ee09e9ef827 Nvim already behaves correctly. Add a screen test as there are none. --- test/functional/ui/popupmenu_spec.lua | 200 ++++++++++++++++++++++++++ test/old/testdir/test_cmdline.vim | 43 ++++++ 2 files changed, 243 insertions(+) diff --git a/test/functional/ui/popupmenu_spec.lua b/test/functional/ui/popupmenu_spec.lua index a1c9cfd846..c84a3c8334 100644 --- a/test/functional/ui/popupmenu_spec.lua +++ b/test/functional/ui/popupmenu_spec.lua @@ -5271,6 +5271,206 @@ describe('builtin popupmenu', function() ) end + -- oldtest: Test_customlist_dict_completion_info_popup() + it('cmdline pum with info popup from customlist', function() + screen:try_resize(55, 12) + exec([[ + func DictComp(A, L, P) + return [ + \ {'word': 'apple', 'kind': 'f', 'menu': 'fruit', 'info': 'A red fruit'}, + \ {'word': 'banana', 'kind': 'f', 'menu': 'fruit', 'info': 'A yellow fruit'}, + \ {'word': 'carrot', 'kind': 'v', 'menu': 'vegetable', 'info': 'An orange vegetable'}, + \ 'plain', + \ ] + endfunc + command -nargs=1 -complete=customlist,DictComp DictCmd echo + set wildmenu wildoptions=pum completeopt=menu,popup + ]]) + + feed(':DictCmd ') + if multigrid then + screen:expect({ + grid = [[ + ## grid 1 + [2:-------------------------------------------------------]|*11 + [3:-------------------------------------------------------]| + ## grid 2 + | + {1:~ }|*10 + ## grid 3 + :DictCmd apple^ | + ## grid 4 + {n:A red fruit}| + ## grid 5 + {12: apple f fruit }| + {n: banana f fruit }| + {n: carrot v vegetable }| + {n: plain }| + ]], + float_pos = { + [5] = { -1, 'SW', 1, 11, 8, false, 250, 3, 7, 8 }, + [4] = { 1001, 'NW', 1, 7, 28, true, 50, 1, 7, 28 }, + }, + }) + else + screen:expect([[ + | + {1:~ }|*6 + {1:~ }{12: apple f fruit }{n:A red fruit}{1: }| + {1:~ }{n: banana f fruit }{1: }| + {1:~ }{n: carrot v vegetable }{1: }| + {1:~ }{n: plain }{1: }| + :DictCmd apple^ | + ]]) + end + + feed('') + if multigrid then + screen:expect({ + grid = [[ + ## grid 1 + [2:-------------------------------------------------------]|*11 + [3:-------------------------------------------------------]| + ## grid 2 + | + {1:~ }|*10 + ## grid 3 + :DictCmd banana^ | + ## grid 4 + {n:A yellow fruit}| + ## grid 5 + {n: apple f fruit }| + {12: banana f fruit }| + {n: carrot v vegetable }| + {n: plain }| + ]], + float_pos = { + [5] = { -1, 'SW', 1, 11, 8, false, 250, 3, 7, 8 }, + [4] = { 1001, 'NW', 1, 7, 28, true, 50, 1, 7, 28 }, + }, + }) + else + screen:expect([[ + | + {1:~ }|*6 + {1:~ }{n: apple f fruit A yellow fruit}{1: }| + {1:~ }{12: banana f fruit }{1: }| + {1:~ }{n: carrot v vegetable }{1: }| + {1:~ }{n: plain }{1: }| + :DictCmd banana^ | + ]]) + end + + feed('') + if multigrid then + screen:expect({ + grid = [[ + ## grid 1 + [2:-------------------------------------------------------]|*11 + [3:-------------------------------------------------------]| + ## grid 2 + | + {1:~ }|*10 + ## grid 3 + :DictCmd carrot^ | + ## grid 4 + {n:An orange vegetable}| + ## grid 5 + {n: apple f fruit }| + {n: banana f fruit }| + {12: carrot v vegetable }| + {n: plain }| + ]], + float_pos = { + [5] = { -1, 'SW', 1, 11, 8, false, 250, 3, 7, 8 }, + [4] = { 1001, 'NW', 1, 7, 28, true, 50, 1, 7, 28 }, + }, + }) + else + screen:expect([[ + | + {1:~ }|*6 + {1:~ }{n: apple f fruit An orange vegetable}{1: }| + {1:~ }{n: banana f fruit }{1: }| + {1:~ }{12: carrot v vegetable }{1: }| + {1:~ }{n: plain }{1: }| + :DictCmd carrot^ | + ]]) + end + + feed('') + if multigrid then + screen:expect({ + grid = [[ + ## grid 1 + [2:-------------------------------------------------------]|*11 + [3:-------------------------------------------------------]| + ## grid 2 + | + {1:~ }|*10 + ## grid 3 + :DictCmd plain^ | + ## grid 4 (hidden) + {n:An orange vegetable}| + ## grid 5 + {n: apple f fruit }| + {n: banana f fruit }| + {n: carrot v vegetable }| + {12: plain }| + ]], + float_pos = { + [5] = { -1, 'SW', 1, 11, 8, false, 250, 2, 7, 8 }, + }, + }) + else + screen:expect([[ + | + {1:~ }|*6 + {1:~ }{n: apple f fruit }{1: }| + {1:~ }{n: banana f fruit }{1: }| + {1:~ }{n: carrot v vegetable }{1: }| + {1:~ }{12: plain }{1: }| + :DictCmd plain^ | + ]]) + end + + feed('') + if multigrid then + screen:expect({ + grid = [[ + ## grid 1 + [2:-------------------------------------------------------]|*11 + [3:-------------------------------------------------------]| + ## grid 2 + | + {1:~ }|*10 + ## grid 3 + :DictCmd ^ | + ## grid 4 (hidden) + {n:An orange vegetable}| + ## grid 5 + {n: apple f fruit }| + {n: banana f fruit }| + {n: carrot v vegetable }| + {n: plain }| + ]], + float_pos = { + [5] = { -1, 'SW', 1, 11, 8, false, 250, 2, 7, 8 }, + }, + }) + else + screen:expect([[ + | + {1:~ }|*6 + {1:~ }{n: apple f fruit }{1: }| + {1:~ }{n: banana f fruit }{1: }| + {1:~ }{n: carrot v vegetable }{1: }| + {1:~ }{n: plain }{1: }| + :DictCmd ^ | + ]]) + end + end) + it("'pumheight'", function() screen:try_resize(32, 8) feed('isome long prefix before the ') diff --git a/test/old/testdir/test_cmdline.vim b/test/old/testdir/test_cmdline.vim index 9637ae5af4..59d0fb68da 100644 --- a/test/old/testdir/test_cmdline.vim +++ b/test/old/testdir/test_cmdline.vim @@ -4624,6 +4624,49 @@ func Test_customlist_dict_completion() delfunc DictCompAbbr endfunc +func Test_customlist_dict_completion_info_popup() + CheckScreendump + + let lines =<< trim END + func DictComp(A, L, P) + return [ + \ {'word': 'apple', 'kind': 'f', 'menu': 'fruit', 'info': 'A red fruit'}, + \ {'word': 'banana', 'kind': 'f', 'menu': 'fruit', 'info': 'A yellow fruit'}, + \ {'word': 'carrot', 'kind': 'v', 'menu': 'vegetable', 'info': 'An orange vegetable'}, + \ 'plain', + \ ] + endfunc + command -nargs=1 -complete=customlist,DictComp DictCmd echo + set wildmenu wildoptions=pum completeopt=menu,popup + END + call writefile(lines, 'XTest_customlist_info_popup', 'D') + let rows = 12 + let buf = RunVimInTerminal('-S XTest_customlist_info_popup', {'rows': rows}) + + call term_sendkeys(buf, ":DictCmd \") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':DictCmd apple') + 1)], g:test_timeout, ((rows - 4), 'A red fruit')) + call VerifyScreenDump(buf, 'Test_customlist_info_popup_1', {}) + + call term_sendkeys(buf, "\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':DictCmd banana') + 1)], g:test_timeout, ((rows - 3), 'A yellow fruit')) + call VerifyScreenDump(buf, 'Test_customlist_info_popup_2', {}) + + call term_sendkeys(buf, "\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':DictCmd carrot') + 1)], g:test_timeout, ((rows - 2), 'An orange vegetable')) + call VerifyScreenDump(buf, 'Test_customlist_info_popup_3', {}) + + call term_sendkeys(buf, "\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':DictCmd plain') + 1)], g:test_timeout, ((rows - 1), '^\~\s\+plain\s\+$')) + call VerifyScreenDump(buf, 'Test_customlist_info_popup_4', {}) + + call term_sendkeys(buf, "\") + call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':DictCmd ') + 1)], g:test_timeout) + call VerifyScreenDump(buf, 'Test_customlist_info_popup_5', {}) + + call term_sendkeys(buf, "\") + call StopVimInTerminal(buf) +endfunc + func Test_custom_completion_with_glob() func TestGlobComplete(A, L, P) return split(glob('Xglob*'), "\n")