patch 9.1.1576: cannot easily trigger wildcard expansion
Commit:
https://github.com/vim/vim/commit/b486ed8266d3b8cd1ffab7d7f302fbd6d5a55c70
Author: Girish Palya <[email protected]>
Date: Mon Jul 21 21:26:32 2025 +0200
patch 9.1.1576: cannot easily trigger wildcard expansion
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 #16759.
closes: #17806
Signed-off-by: Girish Palya <[email protected]>
Co-authored-by: zeertzjq <[email protected]>
Signed-off-by: Christian Brabandt <[email protected]>
diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt
index e1847b1d3..c7d3b401f 100644
--- a/runtime/doc/builtin.txt
+++ b/runtime/doc/builtin.txt
@@ -1,4 +1,4 @@
-*builtin.txt* For Vim version 9.1. Last change: 2025 Jul 17
+*builtin.txt* For Vim version 9.1. Last change: 2025 Jul 21
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -757,6 +757,7 @@ virtcol2col({winid}, {lnum}, {col})
Number byte index of a character on screen
visualmode([{expr}]) String last visual mode used
wildmenumode() Number whether 'wildmenu' mode is active
+wildtrigger() Number start wildcard expansion
win_execute({id}, {command} [, {silent}])
String execute {command} in window {id}
win_findbuf({bufnr}) List find windows containing {bufnr}
@@ -12331,6 +12332,33 @@ wildmenumode()
*wildmenumode()*
Return type: |Number|
+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: >
+ autocmd CmdlineChanged [:/?] call wildtrigger()
+ set wildmode=noselect:lastused,full wildoptions=pum
+<
+ To retain normal history navigation (up/down keys): >
+ cnoremap <Up> <C-U><Up>
+ cnoremap <Down> <C-U><Down>
+<
+ Return value is always 0.
+
+ Return type: |Number|
+
+
win_execute({id}, {command} [, {silent}]) *win_execute()*
Like `execute()` but in the context of window {id}.
The window will temporarily be made the current window,
diff --git a/runtime/doc/cmdline.txt b/runtime/doc/cmdline.txt
index a15debe5e..edc0f0fc3 100644
--- a/runtime/doc/cmdline.txt
+++ b/runtime/doc/cmdline.txt
@@ -1,4 +1,4 @@
-*cmdline.txt* For Vim version 9.1. Last change: 2025 Jun 28
+*cmdline.txt* For Vim version 9.1. Last change: 2025 Jul 21
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -479,6 +479,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,
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
line.
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index d4bdc8196..0a1d955fb 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -1,4 +1,4 @@
-*options.txt* For Vim version 9.1. Last change: 2025 Jul 20
+*options.txt* For Vim version 9.1. Last change: 2025 Jul 21
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -9797,7 +9797,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
|/|, |?|, |:s|, |:g|, |:v|, and |:vim|. To insert a literal <Tab>
instead of triggering completion, type <C-V><Tab> or " ".
- See also |'wildoptions'|.
+ See also 'wildoptions' and |wildtrigger()|.
NOTE: This option is set to the Vi default value when 'compatible' is
set and to the Vim default value when 'compatible' is reset.
diff --git a/runtime/doc/tags b/runtime/doc/tags
index 8e2fb0e96..5535036b2 100644
--- a/runtime/doc/tags
+++ b/runtime/doc/tags
@@ -6620,6 +6620,7 @@ cmdarg-variable eval.txt /*cmdarg-variable*
cmdbang-variable eval.txt /*cmdbang-variable*
cmdcomplete_info() builtin.txt /*cmdcomplete_info()*
cmdline-arguments vi_diff.txt /*cmdline-arguments*
+cmdline-autocompletion builtin.txt /*cmdline-autocompletion*
cmdline-changed version5.txt /*cmdline-changed*
cmdline-completion cmdline.txt /*cmdline-completion*
cmdline-editing cmdline.txt /*cmdline-editing*
@@ -11608,6 +11609,7 @@ whitespace pattern.txt /*whitespace*
wildcard editing.txt /*wildcard*
wildcards editing.txt /*wildcards*
wildmenumode() builtin.txt /*wildmenumode()*
+wildtrigger() builtin.txt /*wildtrigger()*
win-scrolled-resized windows.txt /*win-scrolled-resized*
win16 os_win32.txt /*win16*
win32 os_win32.txt /*win32*
diff --git a/runtime/doc/usr_41.txt b/runtime/doc/usr_41.txt
index 02d58f0d8..d263bed9e 100644
--- a/runtime/doc/usr_41.txt
+++ b/runtime/doc/usr_41.txt
@@ -1,4 +1,4 @@
-*usr_41.txt* For Vim version 9.1. Last change: 2025 Jul 05
+*usr_41.txt* For Vim version 9.1. Last change: 2025 Jul 21
VIM USER MANUAL - by Bram Moolenaar
@@ -1233,6 +1233,7 @@ Mappings and Menus:
*mapping-functions*
mapset() restore a mapping
menu_info() get information about a menu item
wildmenumode() check if the wildmode is active
+ wildtrigger() start wildcard expansion
Testing: *test-functions*
assert_equal() assert that two expressions values are equal
diff --git a/runtime/doc/version9.txt b/runtime/doc/version9.txt
index b49b86a2b..79aec13ad 100644
--- a/runtime/doc/version9.txt
+++ b/runtime/doc/version9.txt
@@ -1,4 +1,4 @@
-*version9.txt* For Vim version 9.1. Last change: 2025 Jul 20
+*version9.txt* For Vim version 9.1. Last change: 2025 Jul 21
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -41601,6 +41601,7 @@ Completion~
"nosort" - do not sort completion results
"preinsert" - highlight to be inserted values
"nearest" - sort completion results by distance to cursor
+- new function |wildtrigger()| to trigger wildcard expansion
Platform specific~
-----------------
@@ -41765,6 +41766,7 @@ Functions: ~
|str2blob()| convert a List of strings into a blob
|test_null_tuple()| return a null tuple
|tuple2list()| turn a Tuple of items into a List
+|wildtrigger()| trigger wildcard expansion
Autocommands: ~
diff --git a/runtime/syntax/vim.vim b/runtime/syntax/vim.vim
index c6f3943d2..4e394d35a 100644
--- a/runtime/syntax/vim.vim
+++ b/runtime/syntax/vim.vim
@@ -2,7 +2,7 @@
" Language: Vim script
" Maintainer: Hirohito Higashi <h.east.727 ATMARK gmail.com>
" Doug Kearns <[email protected]>
-" Last Change: 2025 Jul 18
+" Last Change: 2025 Jul 21
" Former Maintainer: Charles E. Campbell
" DO NOT CHANGE DIRECTLY.
@@ -141,7 +141,7 @@ syn match vimUserAutoEvent contained
"\<\h\w*\>" skipwhite nextgroup=vimUserAuto
" Highlight commonly used Groupnames {{{2
" 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
" GEN_SYN_VIM: vimHLGroup, START_STR='syn keyword vimHLGroup contained',
END_STR=''
@@ -159,8 +159,8 @@ syn keyword vimFuncName contained histadd histdel histget
histnr hlID hlexists h
syn keyword vimFuncName contained mzeval nextnonblank ngettext nr2char or
pathshorten perleval popup_atcursor popup_beval popup_clear popup_close
popup_create popup_dialog popup_filter_menu popup_filter_yesno popup_findecho
popup_findinfo popup_findpreview popup_getoptions popup_getpos popup_hide
popup_list popup_locate popup_menu popup_move popup_notification popup_setbuf
popup_setoptions popup_settext popup_show pow prevnonblank printf
prompt_getprompt prompt_setcallback prompt_setinterrupt prompt_setprompt
prop_add prop_add_list prop_clear prop_find prop_list prop_remove prop_type_add
prop_type_change prop_type_delete prop_type_get prop_type_list pum_getpos
pumvisible py3eval pyeval pyxeval rand range readblob readdir readdirex
readfile reduce reg_executing
syn keyword vimFuncName contained reg_recording reltime reltimefloat
reltimestr remote_expr remote_foreground remote_peek remote_read remote_send
remote_startserver remove rename repeat resolve reverse round rubyeval
screenattr screenchar screenchars screencol screenpos screenrow screenstring
search searchcount searchdecl searchpair searchpairpos searchpos server2client
serverlist setbufline setbufvar setcellwidths setcharpos setcharsearch
setcmdline setcmdpos setcursorcharpos setenv setfperm setline setloclist
setmatches setpos setqflist setreg settabvar settabwinvar settagstack setwinvar
sha256 shellescape shiftwidth sign_define sign_getdefined sign_getplaced
sign_jump sign_place sign_placelist sign_undefine sign_unplace sign_unplacelist
simplify sin sinh slice
syn keyword vimFuncName contained sort sound_clear sound_playevent
sound_playfile sound_stop soundfold spellbadword spellsuggest split sqrt srand
state str2blob str2float str2list str2nr strcharlen strcharpart strchars
strdisplaywidth strftime strgetchar stridx string strlen strpart strptime
strridx strtrans strutf16len strwidth submatch substitute swapfilelist swapinfo
swapname synID synIDattr synIDtrans synconcealed synstack system systemlist
tabpagebuflist tabpagenr tabpagewinnr tagfiles taglist tan tanh tempname
term_dumpdiff term_dumpload term_dumpwrite term_getaltscreen term_getansicolors
term_getattr term_getcursor term_getjob term_getline term_getscrolled
term_getsize term_getstatus term_gettitle term_gettty term_list term_scrape
term_sendkeys term_setansicolors
-syn keyword vimFuncName contained term_setapi term_setkill term_setrestore
term_setsize term_start term_wait terminalprops test_alloc_fail test_autochdir
test_feedinput test_garbagecollect_now test_garbagecollect_soon test_getvalue
test_gui_event test_ignore_error test_mswin_event test_null_blob
test_null_channel test_null_dict test_null_function test_null_job
test_null_list test_null_partial test_null_string test_null_tuple
test_option_not_set test_override test_refcount test_setmouse test_settime
test_srand_seed test_unknown test_void timer_info timer_pause timer_start
timer_stop timer_stopall tolower toupper tr trim trunc tuple2list type typename
undofile undotree uniq utf16idx values virtcol virtcol2col visualmode
wildmenumode win_execute win_findbuf win_getid
-syn keyword vimFuncName contained win_gettype win_gotoid win_id2tabwin
win_id2win win_move_separator win_move_statusline win_screenpos win_splitmove
winbufnr wincol windowsversion winheight winlayout winline winnr winrestcmd
winrestview winsaveview winwidth wordcount writefile xor
+syn keyword vimFuncName contained term_setapi term_setkill term_setrestore
term_setsize term_start term_wait terminalprops test_alloc_fail test_autochdir
test_feedinput test_garbagecollect_now test_garbagecollect_soon test_getvalue
test_gui_event test_ignore_error test_mswin_event test_null_blob
test_null_channel test_null_dict test_null_function test_null_job
test_null_list test_null_partial test_null_string test_null_tuple
test_option_not_set test_override test_refcount test_setmouse test_settime
test_srand_seed test_unknown test_void timer_info timer_pause timer_start
timer_stop timer_stopall tolower toupper tr trim trunc tuple2list type typename
undofile undotree uniq utf16idx values virtcol virtcol2col visualmode
wildmenumode wildtrigger win_execute win_findbuf
+syn keyword vimFuncName contained win_getid win_gettype win_gotoid
win_id2tabwin win_id2win win_move_separator win_move_statusline win_screenpos
win_splitmove winbufnr wincol windowsversion winheight winlayout winline winnr
winrestcmd winrestview winsaveview winwidth wordcount writefile xor
" Predefined variable names {{{2
" GEN_SYN_VIM: vimVarName, START_STR='syn keyword vimVimVarName contained',
END_STR=''
syn keyword vimVimVarName contained count count1 prevcount errmsg warningmsg
statusmsg shell_error this_session version lnum termresponse fname lang lc_time
ctype charconvert_from charconvert_to fname_in fname_out fname_new fname_diff
cmdarg foldstart foldend folddashes foldlevel progname servername dying
exception throwpoint register cmdbang insertmode val key profiling fcs_reason
fcs_choice beval_bufnr beval_winnr beval_winid beval_lnum beval_col beval_text
scrollstart swapname swapchoice swapcommand char mouse_win mouse_winid
mouse_lnum mouse_col operator searchforward hlsearch oldfiles windowid progpath
completed_item option_new option_old option_oldlocal option_oldglobal
option_command option_type errors false true none null numbermax numbermin
numbersize
diff --git a/src/cmdexpand.c b/src/cmdexpand.c
index a7a5acf95..bddfe8ca6 100644
--- a/src/cmdexpand.c
+++ b/src/cmdexpand.c
@@ -238,6 +238,7 @@ nextwild(
cmdline_info_T *ccline = get_cmdline_info();
int i;
char_u *p;
+ int from_wildtrigger_func = options & WILD_FUNC_TRIGGER;
if (xp->xp_numfiles == -1)
{
@@ -269,17 +270,22 @@ nextwild(
return FAIL;
}
+ i = (int)(xp->xp_pattern - ccline->cmdbuff);
+ xp->xp_pattern_len = ccline->cmdpos - 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)
+ if (!cmd_silent && !from_wildtrigger_func)
{
msg_puts("..."); // show that we are busy
out_flush();
}
- i = (int)(xp->xp_pattern - ccline->cmdbuff);
- xp->xp_pattern_len = ccline->cmdpos - i;
-
if (type == WILD_NEXT || type == WILD_PREV
|| type == WILD_PAGEUP || type == WILD_PAGEDOWN)
{
diff --git a/src/evalfunc.c b/src/evalfunc.c
index ec21087e2..3c8339ee3 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -3126,6 +3126,8 @@ static funcentry_T global_functions[] =
ret_string, f_visualmode},
{"wildmenumode", 0, 0, 0, NULL,
ret_number, f_wildmenumode},
+ {"wildtrigger", 0, 0, 0, NULL,
+ ret_void, f_wildtrigger},
{"win_execute", 2, 3, FEARG_2, arg23_win_execute,
ret_string, f_win_execute},
{"win_findbuf", 1, 1, FEARG_1, arg1_number,
diff --git a/src/ex_getln.c b/src/ex_getln.c
index 5ee94d219..560324c6e 100644
--- a/src/ex_getln.c
+++ b/src/ex_getln.c
@@ -957,9 +957,11 @@ cmdline_wildchar_complete(
}
else // typed p_wc first time
{
- if (c == p_wc || c == p_wcm)
+ if (c == p_wc || c == p_wcm || c == K_WILD)
{
options |= WILD_MAY_EXPAND_PATTERN;
+ if (c == K_WILD)
+ options |= WILD_FUNC_TRIGGER;
if (pre_incsearch_pos)
xp->xp_pre_incsearch_pos = *pre_incsearch_pos;
else
@@ -1395,7 +1397,7 @@ cmdline_browse_history(
for (;;)
{
// one step backwards
- if (c == K_UP|| c == K_S_UP || c == Ctrl_P
+ if (c == K_UP || c == K_S_UP || c == Ctrl_P
|| c == K_PAGEUP || c == K_KPAGEUP)
{
if (hiscnt == get_hislen()) // first time
@@ -1818,9 +1820,9 @@ getcmdline_int(
*/
for (;;)
{
- int trigger_cmdlinechanged = TRUE;
- int end_wildmenu;
- int prev_cmdpos = ccline.cmdpos;
+ int trigger_cmdlinechanged = TRUE;
+ int end_wildmenu;
+ int prev_cmdpos = ccline.cmdpos;
VIM_CLEAR(prev_cmdbuff);
@@ -2058,9 +2060,11 @@ getcmdline_int(
}
}
- // Completion for 'wildchar' or 'wildcharm' key.
- if ((c == p_wc && !gotesc && KeyTyped) || c == p_wcm)
+ // Completion for 'wildchar', 'wildcharm', and wildtrigger()
+ if ((c == p_wc && !gotesc && KeyTyped) || c == p_wcm || c == K_WILD)
{
+ if (c == K_WILD)
+ ++emsg_silent; // Silence the bell
res = cmdline_wildchar_complete(c, firstc != '@', &did_wild_list,
&wim_index, &xpc, &gotesc,
#ifdef FEAT_SEARCH_EXTRA
@@ -2069,8 +2073,12 @@ getcmdline_int(
NULL
#endif
);
+ if (c == K_WILD)
+ --emsg_silent;
if (res == CMDLINE_CHANGED)
goto cmdline_changed;
+ if (c == K_WILD)
+ goto cmdline_not_changed;
}
gotesc = FALSE;
@@ -5109,3 +5117,30 @@ get_user_input(
cmd_silent = cmd_silent_save;
}
#endif
+
+/*
+ * "wildtrigger()" function
+ */
+ void
+f_wildtrigger(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
+{
+ if (!(State & MODE_CMDLINE) || char_avail() || wild_menu_showing
+ || 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
+ char_u 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(key_string, REMAP_NONE, 0, TRUE, FALSE);
+ }
+}
diff --git a/src/keymap.h b/src/keymap.h
index 29e2a055c..e993e0999 100644
--- a/src/keymap.h
+++ b/src/keymap.h
@@ -279,6 +279,7 @@ enum key_extra
, KE_S_BS = 105 // shift + <BS>
, KE_SID = 106 // <SID> special key, followed by {nr};
, KE_ESC = 107 // used for K_ESC
+ , KE_WILD = 108 // triggers wildmode completion
};
/*
@@ -491,6 +492,8 @@ enum key_extra
#define K_SCRIPT_COMMAND TERMCAP2KEY(KS_EXTRA, KE_SCRIPT_COMMAND)
#define K_SID TERMCAP2KEY(KS_EXTRA, KE_SID)
+#define K_WILD TERMCAP2KEY(KS_EXTRA, KE_WILD)
+
// Bits for modifier mask
// 0x01 cannot be used, because the modifier must be 0x02 or higher
#define MOD_MASK_SHIFT 0x02
diff --git a/src/proto/ex_getln.pro b/src/proto/ex_getln.pro
index 6c93ac755..7270469a2 100644
--- a/src/proto/ex_getln.pro
+++ b/src/proto/ex_getln.pro
@@ -39,6 +39,7 @@ void f_getcmdscreenpos(typval_T *argvars, typval_T *rettv);
void f_getcmdtype(typval_T *argvars, typval_T *rettv);
void f_setcmdline(typval_T *argvars, typval_T *rettv);
void f_setcmdpos(typval_T *argvars, typval_T *rettv);
+void f_wildtrigger(typval_T *argvars, typval_T *rettv);
int get_cmdline_firstc(void);
int get_list_range(char_u **str, int *num1, int *num2);
char *did_set_cedit(optset_T *args);
diff --git a/src/testdir/test_cmdline.vim b/src/testdir/test_cmdline.vim
index 697b01acd..4e4d34caa 100644
--- a/src/testdir/test_cmdline.vim
+++ b/src/testdir/test_cmdline.vim
@@ -4329,42 +4329,63 @@ func Test_cmdcomplete_info()
autocmd CmdlineLeavePre * call expand('test_cmdline.*')
autocmd CmdlineLeavePre * let g:cmdcomplete_info =
string(cmdcomplete_info())
augroup END
- new
+
+ " Disable char_avail so that wildtrigger() does not bail out
+ call test_override("char_avail", 1)
+
+ cnoremap <F8> <C-R>=wildtrigger()[-1]<CR>
+
call assert_equal({}, cmdcomplete_info())
- call feedkeys(":h echom\<cr>", "tx") " No expansion
- call assert_equal('{}', g:cmdcomplete_info)
- call feedkeys(":h echoms\<tab>\<cr>", "tx")
- call assert_equal('{''cmdline_orig'': '''', ''pum_visible'': 0, ''matches'':
[], ''selected'': 0}', g:cmdcomplete_info)
- call feedkeys(":h echom\<tab>\<cr>", "tx")
- call assert_equal(
- \ '{''cmdline_orig'': ''h echom'', ''pum_visible'': 0, ''matches'':
['':echom'', '':echomsg''], ''selected'': 0}',
- \ g:cmdcomplete_info)
- call feedkeys(":h echom\<tab>\<tab>\<cr>", "tx")
- call assert_equal(
- \ '{''cmdline_orig'': ''h echom'', ''pum_visible'': 0, ''matches'':
['':echom'', '':echomsg''], ''selected'': 1}',
- \ g:cmdcomplete_info)
- call feedkeys(":h echom\<tab>\<tab>\<tab>\<cr>", "tx")
- call assert_equal(
- \ '{''cmdline_orig'': ''h echom'', ''pum_visible'': 0, ''matches'':
['':echom'', '':echomsg''], ''selected'': -1}',
- \ g:cmdcomplete_info)
- set wildoptions=pum
- call feedkeys(":h echoms\<tab>\<cr>", "tx")
- call assert_equal('{''cmdline_orig'': '''', ''pum_visible'': 0, ''matches'':
[], ''selected'': 0}', g:cmdcomplete_info)
- call feedkeys(":h echom\<tab>\<cr>", "tx")
- call assert_equal(
- \ '{''cmdline_orig'': ''h echom'', ''pum_visible'': 1, ''matches'':
['':echom'', '':echomsg''], ''selected'': 0}',
- \ g:cmdcomplete_info)
- call feedkeys(":h echom\<tab>\<tab>\<cr>", "tx")
- call assert_equal(
- \ '{''cmdline_orig'': ''h echom'', ''pum_visible'': 1, ''matches'':
['':echom'', '':echomsg''], ''selected'': 1}',
- \ g:cmdcomplete_info)
- call feedkeys(":h echom\<tab>\<tab>\<tab>\<cr>", "tx")
- call assert_equal(
- \ '{''cmdline_orig'': ''h echom'', ''pum_visible'': 1, ''matches'':
['':echom'', '':echomsg''], ''selected'': -1}',
- \ g:cmdcomplete_info)
- bw!
- set wildoptions&
+ for trig in ["\<Tab>", "\<F8>"]
+ new
+ call assert_equal({}, cmdcomplete_info())
+ call feedkeys(":h echom\<cr>", "tx") " No expansion
+ call assert_equal('{}', g:cmdcomplete_info)
+ call feedkeys($":h echoms{trig}\<cr>", "tx")
+ call assert_equal('{''cmdline_orig'': '''', ''pum_visible'': 0,
''matches'': [], ''selected'': 0}', g:cmdcomplete_info)
+ call feedkeys($":h echom{trig}\<cr>", "tx")
+ call assert_equal(
+ \ '{''cmdline_orig'': ''h echom'', ''pum_visible'': 0, ''matches'':
['':echom'', '':echomsg''], ''selected'': 0}',
+ \ g:cmdcomplete_info)
+ call feedkeys($":h echom{trig}\<tab>\<cr>", "tx")
+ call assert_equal(
+ \ '{''cmdline_orig'': ''h echom'', ''pum_visible'': 0, ''matches'':
['':echom'', '':echomsg''], ''selected'': 1}',
+ \ g:cmdcomplete_info)
+ call feedkeys($":h echom{trig}\<tab>\<tab>\<cr>", "tx")
+ call assert_equal(
+ \ '{''cmdline_orig'': ''h echom'', ''pum_visible'': 0, ''matches'':
['':echom'', '':echomsg''], ''selected'': -1}',
+ \ g:cmdcomplete_info)
+
+ set wildoptions=pum
+ call feedkeys($":h echoms{trig}\<cr>", "tx")
+ call assert_equal('{''cmdline_orig'': '''', ''pum_visible'': 0,
''matches'': [], ''selected'': 0}', g:cmdcomplete_info)
+ call feedkeys($":h echom{trig}\<cr>", "tx")
+ call assert_equal(
+ \ '{''cmdline_orig'': ''h echom'', ''pum_visible'': 1, ''matches'':
['':echom'', '':echomsg''], ''selected'': 0}',
+ \ g:cmdcomplete_info)
+ call feedkeys($":h echom{trig}\<tab>\<cr>", "tx")
+ call assert_equal(
+ \ '{''cmdline_orig'': ''h echom'', ''pum_visible'': 1, ''matches'':
['':echom'', '':echomsg''], ''selected'': 1}',
+ \ g:cmdcomplete_info)
+ call feedkeys($":h echom{trig}\<tab>\<tab>\<cr>", "tx")
+ call assert_equal(
+ \ '{''cmdline_orig'': ''h echom'', ''pum_visible'': 1, ''matches'':
['':echom'', '':echomsg''], ''selected'': -1}',
+ \ g:cmdcomplete_info)
+ bw!
+ set wildoptions&
+ 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 test_override("char_avail", 0)
+ unlet g:cmdcomplete_info
+ cunmap <F8>
endfunc
func Test_redrawtabpanel_error()
@@ -4387,6 +4408,7 @@ func Test_search_complete()
new
cnoremap <buffer><expr> <F9> GetComplInfo()
+ cnoremap <buffer> <F8> <C-R>=wildtrigger()[-1]<CR>
" Pressing <Tab> inserts tab character
set wildchar=0
@@ -4397,7 +4419,7 @@ func Test_search_complete()
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
call feedkeys($"gg2j/t{trig}\<f9>", 'tx')
call assert_equal(['the', 'thethere', 'there', 'these', 'thethe'],
g:compl_info.matches)
@@ -4610,10 +4632,11 @@ func Test_range_complete()
endfunc
new
cnoremap <buffer><expr> <F9> GetComplInfo()
+ cnoremap <buffer> <F8> <C-R>=wildtrigger()[-1]<CR>
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 assert_equal(['ab', 'a', 'af'], g:compl_info.matches)
call feedkeys($":vim9cmd :%s/a{trig}\<f9>", 'xt')
@@ -4699,25 +4722,35 @@ func Test_cmdline_changed()
autocmd CmdlineChanged * if getcmdline() =~ g:cmdprefix | let
g:cmdchg_count += 1 | endif
augroup END
+ " Disable char_avail so that wildtrigger() does not bail out
+ call test_override("char_avail", 1)
+
new
+ cnoremap <buffer> <F8> <C-R>=wildtrigger()[-1]<CR>
set wildmenu
set wildmode=full
let g:cmdprefix = 'echomsg'
- let g:cmdchg_count = 0
- call feedkeys(":echomsg\<Tab>", "tx")
- call assert_equal(1, g:cmdchg_count) " once only for 'g', not again for <Tab>
+ for trig in ["\<Tab>", "\<F8>"]
+ let g:cmdchg_count = 0
+ call feedkeys($":echomsg{trig}", "tx")
+ 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'
- call feedkeys(":ech\<Tab>", "tx")
- call assert_equal(1, g:cmdchg_count) " (once for 'h' and) once for 'o'
+ 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'
+ endfor
set wildmode=noselect,full
- let g:cmdchg_count = 0
let g:cmdprefix = 'ech'
- call feedkeys(":ech\<Tab>", "tx")
- call assert_equal(1, g:cmdchg_count) " once for 'h', not again for <tab>
+ 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>
+ endfor
command! -nargs=+ -complete=custom,TestComplete Test echo
@@ -4726,10 +4759,12 @@ func Test_cmdline_changed()
endfunc
set wildoptions=fuzzy wildmode=full
- let g:cmdchg_count = 0
let g:cmdprefix = 'Test \(AbC\|abc\)'
- call feedkeys(":Test abc\<Tab>", "tx")
- call assert_equal(2, g:cmdchg_count) " once for 'c', again for 'AbC'
+ 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'
+ endfor
bw!
set wildmode& wildmenu& wildoptions&
@@ -4738,6 +4773,7 @@ func Test_cmdline_changed()
unlet g:cmdprefix
delfunc TestComplete
delcommand Test
+ call test_override("char_avail", 0)
endfunc
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index 8e4cfcc2b..11357b22e 100644
--- a/src/version.c
+++ b/src/version.c
@@ -719,6 +719,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 1576,
/**/
1575,
/**/
diff --git a/src/vim.h b/src/vim.h
index 74a349dcc..94a10a322 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -897,6 +897,7 @@ extern int (*dyn_libintl_wputenv)(const wchar_t *envstring);
#define BUF_DIFF_FILTER 0x2000
#define WILD_KEEP_SOLE_ITEM 0x4000
#define WILD_MAY_EXPAND_PATTERN 0x8000
+#define WILD_FUNC_TRIGGER 0x10000 // called from wildtrigger()
// Flags for expand_wildcards()
#define EW_DIR 0x01 // include directory names
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion visit
https://groups.google.com/d/msgid/vim_dev/E1udwRg-002B9t-99%40256bit.org.