fix(cmdline): do not trigger completion at wrong time (#19920)

Cherry-picked from Vim patches 8.2.4339, 9.0.0238.
This commit is contained in:
zeertzjq
2022-08-24 10:28:32 +08:00
committed by GitHub
parent 64d147b471
commit 9a100ee169
3 changed files with 82 additions and 10 deletions

View File

@@ -1277,8 +1277,11 @@ static int command_line_execute(VimState *state, int key)
// <S-Tab> goes to last match, in a clumsy way // <S-Tab> goes to last match, in a clumsy way
if (s->c == K_S_TAB && KeyTyped) { if (s->c == K_S_TAB && KeyTyped) {
if (nextwild(&s->xpc, WILD_EXPAND_KEEP, 0, s->firstc != '@') == OK) { if (nextwild(&s->xpc, WILD_EXPAND_KEEP, 0, s->firstc != '@') == OK) {
// Trigger the popup menu when wildoptions=pum if (s->xpc.xp_numfiles > 1
showmatches(&s->xpc, p_wmnu && ((wim_flags[s->wim_index] & WIM_LIST) == 0)); && ((!s->did_wild_list && (wim_flags[s->wim_index] & WIM_LIST)) || p_wmnu)) {
// Trigger the popup menu when wildoptions=pum
showmatches(&s->xpc, p_wmnu && ((wim_flags[s->wim_index] & WIM_LIST) == 0));
}
nextwild(&s->xpc, WILD_PREV, 0, s->firstc != '@'); nextwild(&s->xpc, WILD_PREV, 0, s->firstc != '@');
nextwild(&s->xpc, WILD_PREV, 0, s->firstc != '@'); nextwild(&s->xpc, WILD_PREV, 0, s->firstc != '@');
return command_line_changed(s); return command_line_changed(s);
@@ -1798,13 +1801,16 @@ static int command_line_handle_key(CommandLineState *s)
return command_line_not_changed(s); return command_line_not_changed(s);
case Ctrl_A: // all matches case Ctrl_A: // all matches
if (cmdline_pum_active()) {
// As Ctrl-A completes all the matches, close the popup
// menu (if present)
cmdline_pum_cleanup(&ccline);
}
if (nextwild(&s->xpc, WILD_ALL, 0, s->firstc != '@') == FAIL) { if (nextwild(&s->xpc, WILD_ALL, 0, s->firstc != '@') == FAIL) {
break; break;
} }
if (cmdline_pum_active()) { s->xpc.xp_context = EXPAND_NOTHING;
cmdline_pum_cleanup(&ccline); s->did_wild_list = false;
s->xpc.xp_context = EXPAND_NOTHING;
}
return command_line_changed(s); return command_line_changed(s);
case Ctrl_L: case Ctrl_L:

View File

@@ -1990,6 +1990,22 @@ describe('builtin popupmenu', function()
efine unplace^ | efine unplace^ |
]]) ]])
-- Pressing <Left> after that should move the cursor
feed('<Left>')
screen:expect([[
|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
{4: }|
:sign define jump list place und|
efine unplac^e |
]])
feed('<End>')
-- Pressing <C-D> when the popup menu is displayed should remove the popup -- Pressing <C-D> when the popup menu is displayed should remove the popup
-- menu -- menu
feed('<C-U>sign <Tab><C-D>') feed('<C-U>sign <Tab><C-D>')

View File

@@ -461,20 +461,20 @@ end)
describe('command line completion', function() describe('command line completion', function()
local screen local screen
before_each(function() before_each(function()
clear()
screen = Screen.new(40, 5) screen = Screen.new(40, 5)
screen:set_default_attr_ids({ screen:set_default_attr_ids({
[1] = {bold = true, foreground = Screen.colors.Blue1}, [1] = {bold = true, foreground = Screen.colors.Blue1},
[2] = {foreground = Screen.colors.Grey0, background = Screen.colors.Yellow}, [2] = {foreground = Screen.colors.Grey0, background = Screen.colors.Yellow},
[3] = {bold = true, reverse = true}, [3] = {bold = true, reverse = true},
}) })
screen:attach()
end) end)
after_each(function() after_each(function()
os.remove('Xtest-functional-viml-compl-dir') os.remove('Xtest-functional-viml-compl-dir')
end) end)
it('lists directories with empty PATH', function() it('lists directories with empty PATH', function()
clear()
screen:attach()
local tmp = funcs.tempname() local tmp = funcs.tempname()
command('e '.. tmp) command('e '.. tmp)
command('cd %:h') command('cd %:h')
@@ -491,8 +491,6 @@ describe('command line completion', function()
end) end)
it('completes env var names #9681', function() it('completes env var names #9681', function()
clear()
screen:attach()
command('let $XTEST_1 = "foo" | let $XTEST_2 = "bar"') command('let $XTEST_1 = "foo" | let $XTEST_2 = "bar"')
command('set wildmenu wildmode=full') command('set wildmenu wildmode=full')
feed(':!echo $XTEST_<tab>') feed(':!echo $XTEST_<tab>')
@@ -521,6 +519,58 @@ describe('command line completion', function()
:!echo $XTEST_1AaあB^ | :!echo $XTEST_1AaあB^ |
]]) ]])
end) end)
it('does not leak memory with <S-Tab> with wildmenu and only one match #19874', function()
meths.set_option('wildmenu', true)
meths.set_option('wildmode', 'full')
meths.set_option('wildoptions', 'pum')
feed(':sign unpla<S-Tab>')
screen:expect([[
|
{1:~ }|
{1:~ }|
{1:~ }|
:sign unplace^ |
]])
feed('<Space>buff<Tab>')
screen:expect([[
|
{1:~ }|
{1:~ }|
{1:~ }|
:sign unplace buffer=^ |
]])
end)
it('does not show matches with <S-Tab> without wildmenu with wildmode=full', function()
meths.set_option('wildmenu', false)
meths.set_option('wildmode', 'full')
feed(':sign <S-Tab>')
screen:expect([[
|
{1:~ }|
{1:~ }|
{1:~ }|
:sign unplace^ |
]])
end)
it('shows matches with <S-Tab> without wildmenu with wildmode=list', function()
meths.set_option('wildmenu', false)
meths.set_option('wildmode', 'list')
feed(':sign <S-Tab>')
screen:expect([[
{3: }|
:sign define |
define list undefine |
jump place unplace |
:sign unplace^ |
]])
end)
end) end)
describe('ui/ext_wildmenu', function() describe('ui/ext_wildmenu', function()