vim-patch:9.1.1737: Patch v9.1.1714 introduce a regression for wildmenu

Problem:  Patch v9.1.1714 introduce a regression for wildmenu (zeertzjq)
Solution: Restore behavior of "longest" in 'wildmode' (Girish Palya)

- Fixed a regression caused by PR vim/vim#18125 selecting wrong item
- Fixed another regression where the first pasted text did not appear on
  the command-line after starting Vim.

closes: vim/vim#18212

8fec92d631

Co-authored-by: Girish Palya <girishji@gmail.com>
This commit is contained in:
zeertzjq
2025-09-07 13:17:29 +08:00
parent 1359578abb
commit f2bda1effc
3 changed files with 150 additions and 22 deletions

View File

@@ -1179,16 +1179,25 @@ static int command_line_wildchar_complete(CommandLineState *s)
// Display matches // Display matches
if (res == OK && s->xpc.xp_numfiles > (wim_noselect ? 0 : 1)) { if (res == OK && s->xpc.xp_numfiles > (wim_noselect ? 0 : 1)) {
// If "longest" fails to identify the longest item, try other if (wim_longest) {
// 'wim' values if available bool found_longest_prefix = (ccline.cmdpos != cmdpos_before);
if (wim_longest && ccline.cmdpos == cmdpos_before) {
if (wim_full) {
nextwild(&s->xpc, WILD_NEXT, options, escape);
}
if (wim_list || (p_wmnu && wim_full)) { if (wim_list || (p_wmnu && wim_full)) {
showmatches(&s->xpc, p_wmnu, wim_list, false); showmatches(&s->xpc, p_wmnu, wim_list, true);
} else if (!found_longest_prefix) {
bool wim_list_next = (wim_flags[1] & kOptWimFlagList);
bool wim_full_next = (wim_flags[1] & kOptWimFlagFull);
bool wim_noselect_next = (wim_flags[1] & kOptWimFlagNoselect);
if (wim_list_next || (p_wmnu && (wim_full_next || wim_noselect_next))) {
if (wim_noselect_next) {
options |= WILD_NOSELECT;
}
if (wim_full_next || wim_noselect_next) {
nextwild(&s->xpc, WILD_NEXT, options, escape);
}
showmatches(&s->xpc, p_wmnu, wim_list_next, wim_noselect_next);
}
} }
} else if (!wim_longest) { } else {
if (wim_list || (p_wmnu && (wim_full || wim_noselect))) { if (wim_list || (p_wmnu && (wim_full || wim_noselect))) {
showmatches(&s->xpc, p_wmnu, wim_list, wim_noselect); showmatches(&s->xpc, p_wmnu, wim_list, wim_noselect);
} else { } else {

View File

@@ -1060,6 +1060,7 @@ describe('builtin popupmenu', function()
[110] = { background = Screen.colors.Grey, foreground = Screen.colors.DarkYellow }, [110] = { background = Screen.colors.Grey, foreground = Screen.colors.DarkYellow },
[111] = { background = Screen.colors.Plum1, foreground = Screen.colors.DarkBlue }, [111] = { background = Screen.colors.Plum1, foreground = Screen.colors.DarkBlue },
[112] = { background = Screen.colors.Plum1, foreground = Screen.colors.DarkGreen }, [112] = { background = Screen.colors.Plum1, foreground = Screen.colors.DarkGreen },
[113] = { background = Screen.colors.Yellow, foreground = Screen.colors.Black },
-- popup non-selected item -- popup non-selected item
n = { background = Screen.colors.Plum1 }, n = { background = Screen.colors.Plum1 },
-- popup scrollbar knob -- popup scrollbar knob
@@ -4694,6 +4695,107 @@ describe('builtin popupmenu', function()
feed('<Esc>') feed('<Esc>')
-- "longest:list" shows list whether it finds a candidate or not
command('set wildmode=longest:list,full wildoptions=')
feed(':cn<Tab>')
screen:expect([[
|
{1:~ }|*3
{3: }|
:cn |
cnewer cnoreabbrev |
cnext cnoremap |
cnfile cnoremenu |
:cn^ |
]])
feed('<Tab>')
screen:expect([[
|
{1:~ }|*2
{3: }|
:cn |
cnewer cnoreabbrev |
cnext cnoremap |
cnfile cnoremenu |
{113:cnewer}{3: cnext cnfile > }|
:cnewer^ |
]])
feed('<Esc>:sign u<Tab>')
screen:expect([[
|
{1:~ }|*5
{3: }|
:sign un |
undefine unplace |
:sign un^ |
]])
-- "longest:full" shows wildmenu whether it finds a candidate or not;
-- item not selected
feed('<Esc>')
command('set wildmode=longest:full,full')
feed(':sign u<Tab>')
screen:expect([[
|
{1:~ }|*7
{3:undefine unplace }|
:sign un^ |
]])
feed('<Tab>')
screen:expect([[
|
{1:~ }|*7
{113:undefine}{3: unplace }|
:sign undefine^ |
]])
feed('<Esc>:cn<Tab>')
screen:expect([[
|
{1:~ }|*7
{3:cnewer cnext cnfile > }|
:cn^ |
]])
feed('<Tab>')
screen:expect([[
|
{1:~ }|*7
{113:cnewer}{3: cnext cnfile > }|
:cnewer^ |
]])
-- If "longest,full" finds a candidate, wildmenu is not shown
feed('<Esc>')
command('set wildmode=longest,full')
feed(':sign u<Tab>')
screen:expect([[
|
{1:~ }|*8
:sign un^ |
]])
-- Subsequent wildchar shows wildmenu
feed('<Tab>')
screen:expect([[
|
{1:~ }|*7
{113:undefine}{3: unplace }|
:sign undefine^ |
]])
-- 'longest' does not find candidate, and displays menu without selecting item
feed('<Esc>')
command('set wildmode=longest,noselect')
feed(':cn<Tab>')
screen:expect([[
|
{1:~ }|*7
{3:cnewer cnext cnfile > }|
:cn^ |
]])
feed('<C-U><Esc>')
command('set wildmode& wildoptions=pum')
-- check positioning with multibyte char in pattern -- check positioning with multibyte char in pattern
command('e långfile1') command('e långfile1')
command('sp långfile2') command('sp långfile2')

View File

@@ -2900,7 +2900,7 @@ func Test_wildmenu_pum()
call term_sendkeys(buf, "\<C-U>set wildmode=longest,list\<CR>") call term_sendkeys(buf, "\<C-U>set wildmode=longest,list\<CR>")
call term_sendkeys(buf, ":cn\<Tab>") call term_sendkeys(buf, ":cn\<Tab>")
call VerifyScreenDump(buf, 'Test_wildmenu_pum_30', {}) call VerifyScreenDump(buf, 'Test_wildmenu_pum_30', {})
call term_sendkeys(buf, "\<Tab>") call term_sendkeys(buf, "s")
call VerifyScreenDump(buf, 'Test_wildmenu_pum_31', {}) call VerifyScreenDump(buf, 'Test_wildmenu_pum_31', {})
" Tests a directory name contained full-width characters. " Tests a directory name contained full-width characters.
@@ -3002,28 +3002,45 @@ func Test_wildmenu_pum()
call term_sendkeys(buf, "\<Esc>:set showtabline& laststatus& lazyredraw&\<CR>") call term_sendkeys(buf, "\<Esc>:set showtabline& laststatus& lazyredraw&\<CR>")
" Verify that if "longest" finds nothing, wildmenu is still shown " "longest:list" shows list whether it finds a candidate or not
call term_sendkeys(buf, ":set wildmode=longest:full,full wildoptions&\<CR>") call term_sendkeys(buf, ":set wildmode=longest:list,full wildoptions&\<CR>")
call term_sendkeys(buf, ":cn\<Tab>")
call TermWait(buf, 50)
call VerifyScreenDump(buf, 'Test_wildmenu_pum_54', {})
" Verify that if "longest" finds nothing, "list" is still shown
call term_sendkeys(buf, "\<Esc>:set wildmode=longest:list,full\<CR>")
call term_sendkeys(buf, ":cn\<Tab>") call term_sendkeys(buf, ":cn\<Tab>")
call TermWait(buf, 50) call TermWait(buf, 50)
call VerifyScreenDump(buf, 'Test_wildmenu_pum_55', {}) call VerifyScreenDump(buf, 'Test_wildmenu_pum_55', {})
call term_sendkeys(buf, "\<Tab>") call term_sendkeys(buf, "\<Tab>")
call TermWait(buf, 50) call TermWait(buf, 50)
call VerifyScreenDump(buf, 'Test_wildmenu_pum_56', {}) call VerifyScreenDump(buf, 'Test_wildmenu_pum_56', {})
call term_sendkeys(buf, "\<Esc>:sign u\<Tab>")
" Verify that if "longest" finds a candidate, wildmenu is not shown call TermWait(buf, 50)
call term_sendkeys(buf, "\<Esc>:set wildmode=longest:full,full wildoptions&\<CR>")
call term_sendkeys(buf, ":sign u\<Tab>")
call VerifyScreenDump(buf, 'Test_wildmenu_pum_57', {}) call VerifyScreenDump(buf, 'Test_wildmenu_pum_57', {})
" "longest:full" shows wildmenu whether it finds a candidate or not; item not selected
call term_sendkeys(buf, "\<Esc>:set wildmode=longest:full,full\<CR>")
call term_sendkeys(buf, ":sign u\<Tab>")
call TermWait(buf, 50)
call VerifyScreenDump(buf, 'Test_wildmenu_pum_58', {})
call term_sendkeys(buf, "\<Tab>")
call TermWait(buf, 50)
call VerifyScreenDump(buf, 'Test_wildmenu_pum_59', {})
call term_sendkeys(buf, "\<Esc>:cn\<Tab>")
call TermWait(buf, 50)
call VerifyScreenDump(buf, 'Test_wildmenu_pum_60', {})
call term_sendkeys(buf, "\<Tab>")
call TermWait(buf, 50)
call VerifyScreenDump(buf, 'Test_wildmenu_pum_61', {})
" If "longest,full" finds a candidate, wildmenu is not shown
call term_sendkeys(buf, "\<Esc>:set wildmode=longest,full\<CR>")
call term_sendkeys(buf, ":sign u\<Tab>")
call VerifyScreenDump(buf, 'Test_wildmenu_pum_62', {})
" Subsequent wildchar shows wildmenu " Subsequent wildchar shows wildmenu
call term_sendkeys(buf, "\<Tab>") call term_sendkeys(buf, "\<Tab>")
call VerifyScreenDump(buf, 'Test_wildmenu_pum_58', {}) call VerifyScreenDump(buf, 'Test_wildmenu_pum_63', {})
" 'longest' does not find candidate, and displays menu without selecting item
call term_sendkeys(buf, "\<Esc>:set wildmode=longest,noselect\<CR>")
call term_sendkeys(buf, ":cn\<Tab>")
call VerifyScreenDump(buf, 'Test_wildmenu_pum_64', {})
call term_sendkeys(buf, "\<C-U>\<Esc>") call term_sendkeys(buf, "\<C-U>\<Esc>")
call StopVimInTerminal(buf) call StopVimInTerminal(buf)