vim-patch:9.1.1576: cannot easily trigger wildcard expansion (#35022)

Problem:  cannot easily trigger wildcard expansion
Solution: Introduce wildtrigger() function
          (Girish Palya)

This PR introduces a new `wildtrigger()` function.

See `:h wildtrigger()`

`wildtrigger()` behaves like pressing the `wildchar,` but provides a
more refined and controlled completion experience:

- Suppresses beeps when no matches are found.
- Avoids displaying irrelevant completions (like full command lists)
  when the prefix is insufficient or doesn't match.
- Skips completion if the typeahead buffer has pending input or if a
  wildmenu is already active.
- Does not print "..." before completion.

This is an improvement on the `feedkeys()` based autocompletion script
given in vim/vim#16759.

closes: vim/vim#17806

b486ed8266

While at it, also make Ctrl-Z trigger search completion.

Co-authored-by: Girish Palya <girishji@gmail.com>
This commit is contained in:
zeertzjq
2025-07-23 06:12:50 +08:00
committed by GitHub
parent 8b5d8dfc73
commit 9377db2545
15 changed files with 243 additions and 65 deletions

View File

@@ -451,6 +451,8 @@ When repeating 'wildchar' or CTRL-N you cycle through the matches, eventually
ending up back to what was typed. If the first match is not what you wanted, ending up back to what was typed. If the first match is not what you wanted,
you can use <S-Tab> or CTRL-P to go straight back to what you typed. you can use <S-Tab> or CTRL-P to go straight back to what you typed.
See also |wildtrigger()|.
The 'wildmenu' option can be set to show the matches just above the command The 'wildmenu' option can be set to show the matches just above the command
line. line.

View File

@@ -296,6 +296,7 @@ VIMSCRIPT
• |cmdcomplete_info()| gets current cmdline completion info. • |cmdcomplete_info()| gets current cmdline completion info.
• |getcompletiontype()| gets command-line completion type for any string. • |getcompletiontype()| gets command-line completion type for any string.
• |prompt_getinput()| gets current user-input in prompt-buffer. • |prompt_getinput()| gets current user-input in prompt-buffer.
• |wildtrigger()| triggers command-line expansion.
============================================================================== ==============================================================================
CHANGED FEATURES *news-changed* CHANGED FEATURES *news-changed*

View File

@@ -7212,7 +7212,7 @@ A jump table for the options with a short description can be found at |Q_op|.
< 'wildchar' also enables completion in search pattern contexts such as < 'wildchar' also enables completion in search pattern contexts such as
|/|, |?|, |:s|, |:g|, |:v|, and |:vim|. To insert a literal <Tab> |/|, |?|, |:s|, |:g|, |:v|, and |:vim|. To insert a literal <Tab>
instead of triggering completion, type <C-V><Tab> or "\t". instead of triggering completion, type <C-V><Tab> or "\t".
See also |'wildoptions'|. See also 'wildoptions' and |wildtrigger()|.
*'wildcharm'* *'wcm'* *'wildcharm'* *'wcm'*
'wildcharm' 'wcm' number (default 0) 'wildcharm' 'wcm' number (default 0)

View File

@@ -1036,6 +1036,7 @@ Mappings and Menus: *mapping-functions*
mapset() restore a mapping mapset() restore a mapping
menu_info() get information about a menu item menu_info() get information about a menu item
wildmenumode() check if the wildmode is active wildmenumode() check if the wildmode is active
wildtrigger() start wildcard expansion
Signs: *sign-functions* Signs: *sign-functions*
sign_define() define or update a sign sign_define() define or update a sign

View File

@@ -11878,6 +11878,33 @@ wildmenumode() *wildmenumode()*
Return: ~ Return: ~
(`any`) (`any`)
wildtrigger() *wildtrigger()*
Start wildcard expansion in the command-line, using the
behavior defined by the 'wildmode' and 'wildoptions' settings.
See |cmdline-completion|.
This function also enables completion in search patterns such
as |/|, |?|, |:s|, |:g|, |:v| and |:vimgrep|.
Unlike pressing 'wildchar' manually, this function does not
produce a beep when no matches are found and generally
operates more quietly. This makes it suitable for triggering
completion automatically, such as from an |:autocmd|.
*cmdline-autocompletion*
Example: To make the completion menu pop up automatically as
you type on the command line, use: >vim
autocmd CmdlineChanged [:/?] call wildtrigger()
set wildmode=noselect:lastused,full wildoptions=pum
<
To retain normal history navigation (up/down keys): >vim
cnoremap <Up> <C-U><Up>
cnoremap <Down> <C-U><Down>
<
Return value is always 0.
Return: ~
(`number`)
win_execute({id}, {command} [, {silent}]) *win_execute()* win_execute({id}, {command} [, {silent}]) *win_execute()*
Like `execute()` but in the context of window {id}. Like `execute()` but in the context of window {id}.
The window will temporarily be made the current window, The window will temporarily be made the current window,

View File

@@ -7865,7 +7865,7 @@ vim.go.ww = vim.go.whichwrap
--- 'wildchar' also enables completion in search pattern contexts such as --- 'wildchar' also enables completion in search pattern contexts such as
--- `/`, `?`, `:s`, `:g`, `:v`, and `:vim`. To insert a literal <Tab> --- `/`, `?`, `:s`, `:g`, `:v`, and `:vim`. To insert a literal <Tab>
--- instead of triggering completion, type <C-V><Tab> or "\t". --- instead of triggering completion, type <C-V><Tab> or "\t".
--- See also `'wildoptions'`. --- See also 'wildoptions' and `wildtrigger()`.
--- ---
--- @type integer --- @type integer
vim.o.wildchar = 9 vim.o.wildchar = 9

View File

@@ -10813,6 +10813,32 @@ function vim.fn.wait(timeout, condition, interval) end
--- @return any --- @return any
function vim.fn.wildmenumode() end function vim.fn.wildmenumode() end
--- Start wildcard expansion in the command-line, using the
--- behavior defined by the 'wildmode' and 'wildoptions' settings.
--- See |cmdline-completion|.
---
--- This function also enables completion in search patterns such
--- as |/|, |?|, |:s|, |:g|, |:v| and |:vimgrep|.
---
--- Unlike pressing 'wildchar' manually, this function does not
--- produce a beep when no matches are found and generally
--- operates more quietly. This makes it suitable for triggering
--- completion automatically, such as from an |:autocmd|.
--- *cmdline-autocompletion*
--- Example: To make the completion menu pop up automatically as
--- you type on the command line, use: >vim
--- autocmd CmdlineChanged [:/?] call wildtrigger()
--- set wildmode=noselect:lastused,full wildoptions=pum
--- <
--- To retain normal history navigation (up/down keys): >vim
--- cnoremap <Up> <C-U><Up>
--- cnoremap <Down> <C-U><Down>
--- <
--- Return value is always 0.
---
--- @return number
function vim.fn.wildtrigger() end
--- Like `execute()` but in the context of window {id}. --- Like `execute()` but in the context of window {id}.
--- The window will temporarily be made the current window, --- The window will temporarily be made the current window,
--- without triggering autocommands or changing directory. When --- without triggering autocommands or changing directory. When

View File

@@ -99,7 +99,7 @@ syn match vimUserAutoEvent contained "\<\h\w*\>" skipwhite nextgroup=vimUserAuto
" Highlight commonly used Groupnames {{{2 " Highlight commonly used Groupnames {{{2
" GEN_SYN_VIM: vimGroup, START_STR='syn keyword vimGroup contained', END_STR='' " GEN_SYN_VIM: vimGroup, START_STR='syn keyword vimGroup contained', END_STR=''
syn keyword vimGroup contained Added Boolean Changed Character Comment Conditional Constant Debug Define Delimiter Error Exception Float Function Identifier Ignore Include Keyword Label Macro Number Operator PreCondit PreProc Removed Repeat Special SpecialChar SpecialComment Statement StorageClass String Structure Tag Todo Type Typedef Underlined syn keyword vimGroup contained Added Bold BoldItalic Boolean Changed Character Comment Conditional Constant Debug Define Delimiter Error Exception Float Function Identifier Ignore Include Italic Keyword Label Macro Number Operator PreCondit PreProc Removed Repeat Special SpecialChar SpecialComment Statement StorageClass String Structure Tag Todo Type Typedef Underlined
" Default highlighting groups {{{2 " Default highlighting groups {{{2
" GEN_SYN_VIM: vimHLGroup, START_STR='syn keyword vimHLGroup contained', END_STR='' " GEN_SYN_VIM: vimHLGroup, START_STR='syn keyword vimHLGroup contained', END_STR=''

View File

@@ -254,6 +254,7 @@ int nextwild(expand_T *xp, int type, int options, bool escape)
{ {
CmdlineInfo *const ccline = get_cmdline_info(); CmdlineInfo *const ccline = get_cmdline_info();
char *p; char *p;
bool from_wildtrigger_func = options & WILD_FUNC_TRIGGER;
if (xp->xp_numfiles == -1) { if (xp->xp_numfiles == -1) {
pre_incsearch_pos = xp->xp_pre_incsearch_pos; pre_incsearch_pos = xp->xp_pre_incsearch_pos;
@@ -280,17 +281,24 @@ int nextwild(expand_T *xp, int type, int options, bool escape)
return FAIL; return FAIL;
} }
// If cmd_silent is set then don't show the dots, because redrawcmd() below
// won't remove them.
if (!cmd_silent && !(ui_has(kUICmdline) || ui_has(kUIWildmenu))) {
msg_puts("..."); // show that we are busy
ui_flush();
}
int i = (int)(xp->xp_pattern - ccline->cmdbuff); int i = (int)(xp->xp_pattern - ccline->cmdbuff);
assert(ccline->cmdpos >= i); assert(ccline->cmdpos >= i);
xp->xp_pattern_len = (size_t)ccline->cmdpos - (size_t)i; xp->xp_pattern_len = (size_t)ccline->cmdpos - (size_t)i;
// Skip showing matches if prefix is invalid during wildtrigger()
if (from_wildtrigger_func && xp->xp_context == EXPAND_COMMANDS
&& xp->xp_pattern_len == 0) {
return FAIL;
}
// If cmd_silent is set then don't show the dots, because redrawcmd() below
// won't remove them.
if (!cmd_silent && !from_wildtrigger_func
&& !(ui_has(kUICmdline) || ui_has(kUIWildmenu))) {
msg_puts("..."); // show that we are busy
ui_flush();
}
if (type == WILD_NEXT || type == WILD_PREV if (type == WILD_NEXT || type == WILD_PREV
|| type == WILD_PAGEUP || type == WILD_PAGEDOWN || type == WILD_PAGEUP || type == WILD_PAGEDOWN
|| type == WILD_PUM_WANT) { || type == WILD_PUM_WANT) {

View File

@@ -42,6 +42,7 @@ enum {
BUF_DIFF_FILTER = 0x2000, BUF_DIFF_FILTER = 0x2000,
WILD_KEEP_SOLE_ITEM = 0x4000, WILD_KEEP_SOLE_ITEM = 0x4000,
WILD_MAY_EXPAND_PATTERN = 0x8000, WILD_MAY_EXPAND_PATTERN = 0x8000,
WILD_FUNC_TRIGGER = 0x10000, ///< called from wildtrigger()
}; };
#ifdef INCLUDE_GENERATED_DECLARATIONS #ifdef INCLUDE_GENERATED_DECLARATIONS

View File

@@ -13069,6 +13069,36 @@ M.funcs = {
params = {}, params = {},
signature = 'wildmenumode()', signature = 'wildmenumode()',
}, },
wildtrigger = {
desc = [==[
Start wildcard expansion in the command-line, using the
behavior defined by the 'wildmode' and 'wildoptions' settings.
See |cmdline-completion|.
This function also enables completion in search patterns such
as |/|, |?|, |:s|, |:g|, |:v| and |:vimgrep|.
Unlike pressing 'wildchar' manually, this function does not
produce a beep when no matches are found and generally
operates more quietly. This makes it suitable for triggering
completion automatically, such as from an |:autocmd|.
*cmdline-autocompletion*
Example: To make the completion menu pop up automatically as
you type on the command line, use: >vim
autocmd CmdlineChanged [:/?] call wildtrigger()
set wildmode=noselect:lastused,full wildoptions=pum
<
To retain normal history navigation (up/down keys): >vim
cnoremap <Up> <C-U><Up>
cnoremap <Down> <C-U><Down>
<
Return value is always 0.
]==],
name = 'wildtrigger',
params = {},
returns = 'number',
signature = 'wildtrigger()',
},
win_execute = { win_execute = {
args = { 2, 3 }, args = { 2, 3 },
base = 2, base = 2,

View File

@@ -1147,8 +1147,11 @@ static int command_line_wildchar_complete(CommandLineState *s)
res = OK; // don't insert 'wildchar' now res = OK; // don't insert 'wildchar' now
} }
} else { // typed p_wc first time } else { // typed p_wc first time
if (s->c == p_wc || s->c == p_wcm) { if (s->c == p_wc || s->c == p_wcm || s->c == K_WILD || s->c == Ctrl_Z) {
options |= WILD_MAY_EXPAND_PATTERN; options |= WILD_MAY_EXPAND_PATTERN;
if (s->c == K_WILD) {
options |= WILD_FUNC_TRIGGER;
}
s->xpc.xp_pre_incsearch_pos = s->is_state.search_start; s->xpc.xp_pre_incsearch_pos = s->is_state.search_start;
} }
s->wim_index = 0; s->wim_index = 0;
@@ -1442,11 +1445,22 @@ static int command_line_execute(VimState *state, int key)
} }
} }
// Completion for 'wildchar' or 'wildcharm' key. // Completion for 'wildchar', 'wildcharm', and wildtrigger()
if ((s->c == p_wc && !s->gotesc && KeyTyped) || s->c == p_wcm || s->c == Ctrl_Z) { if ((s->c == p_wc && !s->gotesc && KeyTyped) || s->c == p_wcm || s->c == K_WILD
if (command_line_wildchar_complete(s) == CMDLINE_CHANGED) { || s->c == Ctrl_Z) {
if (s->c == K_WILD) {
emsg_silent++; // Silence the bell
}
int res = command_line_wildchar_complete(s);
if (s->c == K_WILD) {
emsg_silent--;
}
if (res == CMDLINE_CHANGED) {
return command_line_changed(s); return command_line_changed(s);
} }
if (s->c == K_WILD) {
return command_line_not_changed(s);
}
} }
s->gotesc = false; s->gotesc = false;
@@ -4907,3 +4921,27 @@ void get_user_input(const typval_T *const argvars, typval_T *const rettv, const
need_wait_return = false; need_wait_return = false;
msg_didout = false; msg_didout = false;
} }
/// "wildtrigger()" function
void f_wildtrigger(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
{
if (!(State & MODE_CMDLINE) || char_avail()
|| (wild_menu_showing != 0 && wild_menu_showing != WM_LIST)
|| cmdline_pum_active()) {
return;
}
int cmd_type = get_cmdline_type();
if (cmd_type == ':' || cmd_type == '/' || cmd_type == '?') {
// Add K_WILD as a single special key
uint8_t key_string[4];
key_string[0] = K_SPECIAL;
key_string[1] = KS_EXTRA;
key_string[2] = KE_WILD;
key_string[3] = NUL;
// Insert it into the typeahead buffer
ins_typebuf((char *)key_string, REMAP_NONE, 0, true, false);
}
}

View File

@@ -215,10 +215,15 @@ enum key_extra {
// KE_FOCUSGAINED = 98, // focus gained // KE_FOCUSGAINED = 98, // focus gained
// KE_FOCUSLOST = 99, // focus lost // KE_FOCUSLOST = 99, // focus lost
KE_MOUSEMOVE = 100, // mouse moved with no button down KE_MOUSEMOVE = 100, // mouse moved with no button down
// KE_CANCEL = 101, // return from vgetc() // KE_MOUSEMOVE_XY = 101,
// KE_CANCEL = 102, // return from vgetc()
KE_EVENT = 102, // event KE_EVENT = 102, // event
KE_LUA = 103, // Lua special key KE_LUA = 103, // Lua special key
KE_COMMAND = 104, // <Cmd> special key KE_COMMAND = 104, // <Cmd> special key
// KE_S_BS = 105,
// KE_SID = 106,
// KE_ESC = 107,
KE_WILD = 108, // triggers wildmode completion
}; };
// the three byte codes are replaced with the following int when using vgetc() // the three byte codes are replaced with the following int when using vgetc()
@@ -451,6 +456,8 @@ enum key_extra {
#define K_COMMAND TERMCAP2KEY(KS_EXTRA, KE_COMMAND) #define K_COMMAND TERMCAP2KEY(KS_EXTRA, KE_COMMAND)
#define K_LUA TERMCAP2KEY(KS_EXTRA, KE_LUA) #define K_LUA TERMCAP2KEY(KS_EXTRA, KE_LUA)
#define K_WILD TERMCAP2KEY(KS_EXTRA, KE_WILD)
// Bits for modifier mask // Bits for modifier mask
// 0x01 cannot be used, because the modifier must be 0x02 or higher // 0x01 cannot be used, because the modifier must be 0x02 or higher
#define MOD_MASK_SHIFT 0x02 #define MOD_MASK_SHIFT 0x02

View File

@@ -10173,7 +10173,7 @@ local options = {
< 'wildchar' also enables completion in search pattern contexts such as < 'wildchar' also enables completion in search pattern contexts such as
|/|, |?|, |:s|, |:g|, |:v|, and |:vim|. To insert a literal <Tab> |/|, |?|, |:s|, |:g|, |:v|, and |:vim|. To insert a literal <Tab>
instead of triggering completion, type <C-V><Tab> or "\t". instead of triggering completion, type <C-V><Tab> or "\t".
See also |'wildoptions'|. See also 'wildoptions' and |wildtrigger()|.
]=], ]=],
full_name = 'wildchar', full_name = 'wildchar',
scope = { 'global' }, scope = { 'global' },

View File

@@ -4361,42 +4361,64 @@ func Test_cmdcomplete_info()
autocmd CmdlineLeavePre * call expand('test_cmdline.*') autocmd CmdlineLeavePre * call expand('test_cmdline.*')
autocmd CmdlineLeavePre * let g:cmdcomplete_info = string(cmdcomplete_info()) autocmd CmdlineLeavePre * let g:cmdcomplete_info = string(cmdcomplete_info())
augroup END augroup END
" Disable char_avail so that wildtrigger() does not bail out
call Ntest_override("char_avail", 1)
cnoremap <F8> <C-R>=wildtrigger()[-1]<CR>
call assert_equal({}, cmdcomplete_info())
for trig in ["\<Tab>", "\<F8>"]
new new
call assert_equal({}, cmdcomplete_info()) call assert_equal({}, cmdcomplete_info())
call feedkeys(":h echom\<cr>", "tx") " No expansion call feedkeys(":h echom\<cr>", "tx") " No expansion
call assert_equal('{}', g:cmdcomplete_info) call assert_equal('{}', g:cmdcomplete_info)
call feedkeys(":h echoms\<tab>\<cr>", "tx") call feedkeys($":h echoms{trig}\<cr>", "tx")
call assert_equal('{''cmdline_orig'': '''', ''pum_visible'': 0, ''matches'': [], ''selected'': 0}', g:cmdcomplete_info) call assert_equal('{''cmdline_orig'': '''', ''pum_visible'': 0, ''matches'': [], ''selected'': 0}', g:cmdcomplete_info)
call feedkeys(":h echom\<tab>\<cr>", "tx") call feedkeys($":h echom{trig}\<cr>", "tx")
call assert_equal( call assert_equal(
\ '{''cmdline_orig'': ''h echom'', ''pum_visible'': 0, ''matches'': ['':echom'', '':echomsg''], ''selected'': 0}', \ '{''cmdline_orig'': ''h echom'', ''pum_visible'': 0, ''matches'': ['':echom'', '':echomsg''], ''selected'': 0}',
\ g:cmdcomplete_info) \ g:cmdcomplete_info)
call feedkeys(":h echom\<tab>\<tab>\<cr>", "tx") call feedkeys($":h echom{trig}\<tab>\<cr>", "tx")
call assert_equal( call assert_equal(
\ '{''cmdline_orig'': ''h echom'', ''pum_visible'': 0, ''matches'': ['':echom'', '':echomsg''], ''selected'': 1}', \ '{''cmdline_orig'': ''h echom'', ''pum_visible'': 0, ''matches'': ['':echom'', '':echomsg''], ''selected'': 1}',
\ g:cmdcomplete_info) \ g:cmdcomplete_info)
call feedkeys(":h echom\<tab>\<tab>\<tab>\<cr>", "tx") call feedkeys($":h echom{trig}\<tab>\<tab>\<cr>", "tx")
call assert_equal( call assert_equal(
\ '{''cmdline_orig'': ''h echom'', ''pum_visible'': 0, ''matches'': ['':echom'', '':echomsg''], ''selected'': -1}', \ '{''cmdline_orig'': ''h echom'', ''pum_visible'': 0, ''matches'': ['':echom'', '':echomsg''], ''selected'': -1}',
\ g:cmdcomplete_info) \ g:cmdcomplete_info)
set wildoptions=pum set wildoptions=pum
call feedkeys(":h echoms\<tab>\<cr>", "tx") call feedkeys($":h echoms{trig}\<cr>", "tx")
call assert_equal('{''cmdline_orig'': '''', ''pum_visible'': 0, ''matches'': [], ''selected'': 0}', g:cmdcomplete_info) call assert_equal('{''cmdline_orig'': '''', ''pum_visible'': 0, ''matches'': [], ''selected'': 0}', g:cmdcomplete_info)
call feedkeys(":h echom\<tab>\<cr>", "tx") call feedkeys($":h echom{trig}\<cr>", "tx")
call assert_equal( call assert_equal(
\ '{''cmdline_orig'': ''h echom'', ''pum_visible'': 1, ''matches'': ['':echom'', '':echomsg''], ''selected'': 0}', \ '{''cmdline_orig'': ''h echom'', ''pum_visible'': 1, ''matches'': ['':echom'', '':echomsg''], ''selected'': 0}',
\ g:cmdcomplete_info) \ g:cmdcomplete_info)
call feedkeys(":h echom\<tab>\<tab>\<cr>", "tx") call feedkeys($":h echom{trig}\<tab>\<cr>", "tx")
call assert_equal( call assert_equal(
\ '{''cmdline_orig'': ''h echom'', ''pum_visible'': 1, ''matches'': ['':echom'', '':echomsg''], ''selected'': 1}', \ '{''cmdline_orig'': ''h echom'', ''pum_visible'': 1, ''matches'': ['':echom'', '':echomsg''], ''selected'': 1}',
\ g:cmdcomplete_info) \ g:cmdcomplete_info)
call feedkeys(":h echom\<tab>\<tab>\<tab>\<cr>", "tx") call feedkeys($":h echom{trig}\<tab>\<tab>\<cr>", "tx")
call assert_equal( call assert_equal(
\ '{''cmdline_orig'': ''h echom'', ''pum_visible'': 1, ''matches'': ['':echom'', '':echomsg''], ''selected'': -1}', \ '{''cmdline_orig'': ''h echom'', ''pum_visible'': 1, ''matches'': ['':echom'', '':echomsg''], ''selected'': -1}',
\ g:cmdcomplete_info) \ g:cmdcomplete_info)
bw! bw!
set wildoptions& " set wildoptions&
set wildoptions= " Accommodate Nvim default
endfor
" wildtrigger() should not show matches when prefix is invalid
for pat in ["", " ", "22"]
call feedkeys($":{pat}\<F8>\<cr>", "tx") " No expansion
call assert_equal('{}', g:cmdcomplete_info)
endfor
augroup test_CmdlineLeavePre | autocmd! | augroup END
call Ntest_override("char_avail", 0)
unlet g:cmdcomplete_info
cunmap <F8>
endfunc endfunc
" Test wildcharm completion for '/' and '?' search " Test wildcharm completion for '/' and '?' search
@@ -4414,6 +4436,7 @@ func Test_search_complete()
new new
cnoremap <buffer><expr> <F9> GetComplInfo() cnoremap <buffer><expr> <F9> GetComplInfo()
cnoremap <buffer> <F8> <C-R>=wildtrigger()[-1]<CR>
" Pressing <Tab> inserts tab character " Pressing <Tab> inserts tab character
set wildchar=0 set wildchar=0
@@ -4424,7 +4447,7 @@ func Test_search_complete()
call setline(1, ['the', 'these', 'thethe', 'thethere', 'foobar']) call setline(1, ['the', 'these', 'thethe', 'thethere', 'foobar'])
for trig in ["\<tab>", "\<c-z>"] for trig in ["\<tab>", "\<c-z>", "\<F8>"]
" Test menu first item and order " Test menu first item and order
call feedkeys($"gg2j/t{trig}\<f9>", 'tx') call feedkeys($"gg2j/t{trig}\<f9>", 'tx')
call assert_equal(['the', 'thethere', 'there', 'these', 'thethe'], g:compl_info.matches) call assert_equal(['the', 'thethere', 'there', 'these', 'thethe'], g:compl_info.matches)
@@ -4637,10 +4660,11 @@ func Test_range_complete()
endfunc endfunc
new new
cnoremap <buffer><expr> <F9> GetComplInfo() cnoremap <buffer><expr> <F9> GetComplInfo()
cnoremap <buffer> <F8> <C-R>=wildtrigger()[-1]<CR>
call setline(1, ['ab', 'ba', 'ca', 'af']) call setline(1, ['ab', 'ba', 'ca', 'af'])
for trig in ["\<tab>", "\<c-z>"] for trig in ["\<tab>", "\<c-z>", "\<F8>"]
call feedkeys($":%s/a{trig}\<f9>", 'xt') call feedkeys($":%s/a{trig}\<f9>", 'xt')
call assert_equal(['ab', 'a', 'af'], g:compl_info.matches) call assert_equal(['ab', 'a', 'af'], g:compl_info.matches)
" call feedkeys($":vim9cmd :%s/a{trig}\<f9>", 'xt') " call feedkeys($":vim9cmd :%s/a{trig}\<f9>", 'xt')
@@ -4727,25 +4751,35 @@ func Test_cmdline_changed()
autocmd CmdlineChanged * if getcmdline() =~ g:cmdprefix | let g:cmdchg_count += 1 | endif autocmd CmdlineChanged * if getcmdline() =~ g:cmdprefix | let g:cmdchg_count += 1 | endif
augroup END augroup END
" Disable char_avail so that wildtrigger() does not bail out
call Ntest_override("char_avail", 1)
new new
cnoremap <buffer> <F8> <C-R>=wildtrigger()[-1]<CR>
set wildmenu set wildmenu
set wildmode=full set wildmode=full
let g:cmdprefix = 'echomsg' let g:cmdprefix = 'echomsg'
for trig in ["\<Tab>", "\<F8>"]
let g:cmdchg_count = 0 let g:cmdchg_count = 0
call feedkeys(":echomsg\<Tab>", "tx") call feedkeys($":echomsg{trig}", "tx")
call assert_equal(1, g:cmdchg_count) " once only for 'g', not again for <Tab> call assert_equal(1, g:cmdchg_count) " once only for 'g', not again for <Tab>
endfor
let g:cmdchg_count = 0
let g:cmdprefix = 'echo' let g:cmdprefix = 'echo'
call feedkeys(":ech\<Tab>", "tx") for trig in ["\<Tab>", "\<F8>"]
let g:cmdchg_count = 0
call feedkeys($":ech{trig}", "tx")
call assert_equal(1, g:cmdchg_count) " (once for 'h' and) once for 'o' call assert_equal(1, g:cmdchg_count) " (once for 'h' and) once for 'o'
endfor
set wildmode=noselect,full set wildmode=noselect,full
let g:cmdchg_count = 0
let g:cmdprefix = 'ech' let g:cmdprefix = 'ech'
call feedkeys(":ech\<Tab>", "tx") for trig in ["\<Tab>", "\<F8>"]
let g:cmdchg_count = 0
call feedkeys($":ech{trig}", "tx")
call assert_equal(1, g:cmdchg_count) " once for 'h', not again for <tab> call assert_equal(1, g:cmdchg_count) " once for 'h', not again for <tab>
endfor
command! -nargs=+ -complete=custom,TestComplete Test echo command! -nargs=+ -complete=custom,TestComplete Test echo
@@ -4754,10 +4788,12 @@ func Test_cmdline_changed()
endfunc endfunc
set wildoptions=fuzzy wildmode=full set wildoptions=fuzzy wildmode=full
let g:cmdchg_count = 0
let g:cmdprefix = 'Test \(AbC\|abc\)' let g:cmdprefix = 'Test \(AbC\|abc\)'
call feedkeys(":Test abc\<Tab>", "tx") for trig in ["\<Tab>", "\<F8>"]
let g:cmdchg_count = 0
call feedkeys($":Test abc{trig}", "tx")
call assert_equal(2, g:cmdchg_count) " once for 'c', again for 'AbC' call assert_equal(2, g:cmdchg_count) " once for 'c', again for 'AbC'
endfor
bw! bw!
set wildmode& wildmenu& wildoptions& set wildmode& wildmenu& wildoptions&
@@ -4766,6 +4802,7 @@ func Test_cmdline_changed()
unlet g:cmdprefix unlet g:cmdprefix
delfunc TestComplete delfunc TestComplete
delcommand Test delcommand Test
call Ntest_override("char_avail", 0)
endfunc endfunc
" vim: shiftwidth=2 sts=2 expandtab " vim: shiftwidth=2 sts=2 expandtab