patch 9.1.1329: cannot get information about command line completion Commit: https://github.com/vim/vim/commit/92f68e26ec36f2c263db5bea4f39d8503e0b741c Author: Girish Palya <giris...@gmail.com> Date: Mon Apr 21 11:12:41 2025 +0200
patch 9.1.1329: cannot get information about command line completion Problem: cannot get information about command line completion Solution: add CmdlineLeavePre autocommand and cmdcomplete_info() Vim script function (Girish Palya) This commit introduces two features to improve introspection and control over command-line completion in Vim: - Add CmdlineLeavePre autocmd event: A new event triggered just before leaving the command line and before CmdlineLeave. It allows capturing completion-related state that is otherwise cleared by the time CmdlineLeave fires. - Add cmdcomplete_info() Vim script function: Returns a Dictionary with details about the current command-line completion state. These are similar in spirit to InsertLeavePre and complete_info(), but focused on command-line mode. **Use case:** In [[PR #16759](https://github.com/vim/vim/pull/16759)], two examples demonstrate command-line completion: one for live grep, and another for fuzzy file finding. However, both examples share two key limitations: 1. **Broken history recall (`<Up>`)** When selecting a completion item via `<Tab>` or `<C-n>`, the original pattern used for searching (e.g., a regex or fuzzy string) is overwritten in the command-line history. This makes it impossible to recall the original query later. This is especially problematic for interactive grep workflows, where it’s useful to recall a previous search and simply select a different match from the menu. 2. **Lack of default selection on `<CR>`** Often, it’s helpful to allow `<CR>` (Enter) to accept the first match in the completion list, even when no item is explicitly selected. This behavior is particularly useful in fuzzy file finding. ---- Below are the updated examples incorporating these improvements: **Live grep, fuzzy find file, fuzzy find buffer:** ```vim command! -nargs=+ -complete=customlist,GrepComplete Grep VisitFile() def GrepComplete(arglead: string, cmdline: string, cursorpos: number): list<any> return arglead->len() > 1 ? systemlist($'grep -REIHns "{arglead}"' .. ' --exclude-dir=.git --exclude=".*" --exclude="tags" --exclude="*.swp"') : [] enddef def VisitFile() if (selected_match != null_string) var qfitem = getqflist({lines: [selected_match]}).items[0] if qfitem->has_key('bufnr') && qfitem.lnum > 0 var pos = qfitem.vcol > 0 ? 'setcharpos' : 'setpos' exec $':b +call\ {pos}(".",\ [0,\ {qfitem.lnum},\ {qfitem.col},\ 0]) {qfitem.bufnr}' setbufvar(qfitem.bufnr, '&buflisted', 1) endif endif enddef nnoremap <leader>g :Grep<space> nnoremap <leader>G :Grep <c-r>=expand("<cword>")<cr> command! -nargs=* -complete=customlist,FuzzyFind Find execute(selected_match != '' ? $'edit {selected_match}' : '') var allfiles: list<string> autocmd CmdlineEnter : allfiles = null_list def FuzzyFind(arglead: string, _: string, _: number): list<string> if allfiles == null_list allfiles = systemlist($'find {get(g:, "fzfind_root", ".")} \! \( -path "*/.git" -prune -o -name "*.swp" \) -type f -follow') endif return arglead == '' ? allfiles : allfiles->matchfuzzy(arglead) enddef nnoremap <leader><space> :<c-r>=execute('let fzfind_root="."')\|''<cr>Find<space><c-@> nnoremap <leader>fv :<c-r>=execute('let fzfind_root="$HOME/.vim"')\|''<cr>Find<space><c-@> nnoremap <leader>fV :<c-r>=execute('let fzfind_root="$VIMRUNTIME"')\|''<cr>Find<space><c-@> command! -nargs=* -complete=customlist,FuzzyBuffer Buffer execute('b ' .. selected_match->matchstr('\d\+')) def FuzzyBuffer(arglead: string, _: string, _: number): list<string> var bufs = execute('buffers', 'silent!')->split(" ") var altbuf = bufs->indexof((_, v) => v =~ '^\s*\d\+\s\+#') if altbuf != -1 [bufs[0], bufs[altbuf]] = [bufs[altbuf], bufs[0]] endif return arglead == '' ? bufs : bufs->matchfuzzy(arglead) enddef nnoremap <leader><bs> :Buffer <c-@> var selected_match = null_string autocmd CmdlineLeavePre : SelectItem() def SelectItem() selected_match = '' if getcmdline() =~ '^\s*\%(Grep\|Find\|Buffer\)\s' var info = cmdcomplete_info() if info != {} && info.pum_visible && !info.matches->empty() selected_match = info.selected != -1 ? info.matches[info.selected] : info.matches[0] setcmdline(info.cmdline_orig). # Preserve search pattern in history endif endif enddef ``` **Auto-completion snippet:** ```vim set wim=noselect:lastused,full wop=pum wcm=<C-@> wmnu autocmd CmdlineChanged : CmdComplete() def CmdComplete() var [cmdline, curpos] = [getcmdline(), getcmdpos()] if getchar(1, {number: true}) == 0 # Typehead is empty (no more pasted input) && !pumvisible() && curpos == cmdline->len() + 1 && cmdline =~ '\%(\w\|[*/:.-]\)$' && cmdline !~ '^\d\+$' # Reduce noise feedkeys("\<C-@>", "ti") SkipCmdlineChanged() # Suppress redundant completion attempts # Remove <C-@> that get inserted when no items are available timer_start(0, (_) => getcmdline()->substitute('\%x00', '', 'g')->setcmdline()) endif enddef cnoremap <expr> <up> SkipCmdlineChanged("\<up>") cnoremap <expr> <down> SkipCmdlineChanged("\<down>") autocmd CmdlineEnter : set bo+=error autocmd CmdlineLeave : set bo-=error def SkipCmdlineChanged(key = ''): string set ei+=CmdlineChanged timer_start(0, (_) => execute('set ei-=CmdlineChanged')) return key != '' ? ((pumvisible() ? "\<c-e>" : '') .. key) : '' enddef ``` These customizable snippets can serve as *lightweight* and *native* alternatives to picker plugins like **FZF** or **Telescope** for common, everyday workflows. Also, live grep snippet can replace **cscope** without the overhead of building its database. closes: #17115 Signed-off-by: Girish Palya <giris...@gmail.com> Signed-off-by: Christian Brabandt <c...@256bit.org> diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt index b9b76ffce..204a9117c 100644 --- a/runtime/doc/autocmd.txt +++ b/runtime/doc/autocmd.txt @@ -1,4 +1,4 @@ -*autocmd.txt* For Vim version 9.1. Last change: 2025 Apr 04 +*autocmd.txt* For Vim version 9.1. Last change: 2025 Apr 21 VIM REFERENCE MANUAL by Bram Moolenaar @@ -398,6 +398,7 @@ Name triggered by ~ |CmdlineChanged| after a change was made to the command-line text |CmdlineEnter| after the cursor moves to the command line |CmdlineLeave| before the cursor leaves the command line +|CmdlineLeavePre| before preparing to leave the command line |InsertEnter| starting Insert mode |InsertChange| when typing <Insert> while in Insert or Replace mode @@ -639,6 +640,18 @@ CmdlineLeave Before leaving the command line; including <afile> is set to a single character, indicating the type of command-line. |cmdwin-char| + *CmdlineLeavePre* +CmdlineLeavePre Just before leaving the command line, and + before |CmdlineLeave|. Useful for capturing + completion info with |cmdcomplete_info()|, as + this information is cleared before + |CmdlineLeave| is triggered. Triggered for + non-interactive use of ":" in a mapping, but + not when using |<Cmd>|. Also triggered when + abandoning the command line by typing CTRL-C + or <Esc>. <afile> is set to a single + character indicating the command-line type. + See |cmdwin-char| for details. *CmdwinEnter* CmdwinEnter After entering the command-line window. Useful for setting options specifically for diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt index b69f6b463..7353776f5 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 Apr 18 +*builtin.txt* For Vim version 9.1. Last change: 2025 Apr 21 VIM REFERENCE MANUAL by Bram Moolenaar @@ -129,6 +129,8 @@ charidx({string}, {idx} [, {countcc} [, {utf16}]]) chdir({dir}) String change current working directory cindent({lnum}) Number C indent for line {lnum} clearmatches([{win}]) none clear all matches +cmdcomplete_info() Dict get current cmdline completion + information col({expr} [, {winid}]) Number column byte index of cursor or mark complete({startcol}, {matches}) none set Insert mode completion complete_add({expr}) Number add completion match @@ -1832,6 +1834,29 @@ clearmatches([{win}]) *clearmatches()* Return type: |Number| +cmdcomplete_info([{what}]) *cmdcomplete_info()* + Returns a |Dictionary| with information about cmdline + completion. See |cmdline-completion|. + The items are: + cmdline_orig The original command-line string before + completion began. + pum_visible |TRUE| if popup menu is visible. + See |pumvisible()|. + matches List of all completion candidates. Each item + is a string. + selected Selected item index. First index is zero. + Index is -1 if no item is selected (showing + typed text only, or the last completion after + no item is selected when using the <Up> or + <Down> keys) + + Returns an empty |Dictionary| if no completion was attempted, + if there was only one candidate and it was fully completed, or + if an error occurred. + + Return type: dict<any> + + col({expr} [, {winid}]) *col()* The result is a Number, which is the byte index of the column position given with {expr}. diff --git a/runtime/doc/tags b/runtime/doc/tags index 961bde3a2..d51afbf0e 100644 --- a/runtime/doc/tags +++ b/runtime/doc/tags @@ -4079,6 +4079,7 @@ Cmdline-mode cmdline.txt /*Cmdline-mode* CmdlineChanged autocmd.txt /*CmdlineChanged* CmdlineEnter autocmd.txt /*CmdlineEnter* CmdlineLeave autocmd.txt /*CmdlineLeave* +CmdlineLeavePre autocmd.txt /*CmdlineLeavePre* CmdwinEnter autocmd.txt /*CmdwinEnter* CmdwinLeave autocmd.txt /*CmdwinLeave* ColorScheme autocmd.txt /*ColorScheme* @@ -6568,6 +6569,7 @@ close_cb channel.txt /*close_cb* closure eval.txt /*closure* 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-changed version5.txt /*cmdline-changed* cmdline-completion cmdline.txt /*cmdline-completion* diff --git a/runtime/doc/usr_41.txt b/runtime/doc/usr_41.txt index 8279e3e99..eca836281 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 Mar 30 +*usr_41.txt* For Vim version 9.1. Last change: 2025 Apr 21 VIM USER MANUAL - by Bram Moolenaar @@ -1111,6 +1111,7 @@ Command line: *command-line-functions* getcmdwintype() return the current command-line window type getcompletion() list of command-line completion matches fullcommand() get full command name + cmdcomplete_info() get current completion information Quickfix and location lists: *quickfix-functions* getqflist() list of quickfix errors diff --git a/runtime/doc/version9.txt b/runtime/doc/version9.txt index 527ed1850..1ef04bd2e 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 Apr 18 +*version9.txt* For Vim version 9.1. Last change: 2025 Apr 21 VIM REFERENCE MANUAL by Bram Moolenaar @@ -41685,6 +41685,7 @@ Functions: ~ |base64_encode()| encode a blob into a base64 string |blob2str()| convert a blob into a List of strings |bindtextdomain()| set message lookup translation base path +|cmdcomplete_info()| get current cmdline completion info |diff()| diff two Lists of strings |filecopy()| copy a file {from} to {to} |foreach()| apply function to List items @@ -41708,6 +41709,7 @@ Functions: ~ Autocommands: ~ +|CmdlineLeavePre| before preparing to leave the command line |CursorMovedC| after the cursor was moved in the command-line |KeyInputPre| before processing any key event in any mode |SessionWritePost| after writing the session file |:mksession| diff --git a/src/autocmd.c b/src/autocmd.c index 392168269..6ee6c11af 100644 --- a/src/autocmd.c +++ b/src/autocmd.c @@ -110,6 +110,7 @@ static keyvalue_T event_tab[NUM_EVENTS] = { KEYVALUE_ENTRY(EVENT_CMDLINECHANGED, "CmdlineChanged"), KEYVALUE_ENTRY(EVENT_CMDLINEENTER, "CmdlineEnter"), KEYVALUE_ENTRY(EVENT_CMDLINELEAVE, "CmdlineLeave"), + KEYVALUE_ENTRY(EVENT_CMDLINELEAVEPRE, "CmdlineLeavePre"), KEYVALUE_ENTRY(EVENT_CMDUNDEFINED, "CmdUndefined"), KEYVALUE_ENTRY(EVENT_CMDWINENTER, "CmdwinEnter"), KEYVALUE_ENTRY(EVENT_CMDWINLEAVE, "CmdwinLeave"), @@ -2253,6 +2254,7 @@ apply_autocmds_group( || event == EVENT_SYNTAX || event == EVENT_CMDLINECHANGED || event == EVENT_CMDLINEENTER + || event == EVENT_CMDLINELEAVEPRE || event == EVENT_CMDLINELEAVE || event == EVENT_CURSORMOVEDC || event == EVENT_CMDWINENTER diff --git a/src/cmdexpand.c b/src/cmdexpand.c index 85422b802..45f69bb2f 100644 --- a/src/cmdexpand.c +++ b/src/cmdexpand.c @@ -32,6 +32,8 @@ static int compl_match_arraysize; // First column in cmdline of the matched item for completion. static int compl_startcol; static int compl_selected; +// cmdline before expansion +static char_u *cmdline_orig = NULL; #define SHOW_MATCH(m) (showtail ? showmatches_gettail(matches[m]) : matches[m]) @@ -432,6 +434,7 @@ cmdline_pum_remove(cmdline_info_T *cclp UNUSED) pum_undisplay(); VIM_CLEAR(compl_match_array); + compl_match_arraysize = 0; p_lz = FALSE; // avoid the popup menu hanging around update_screen(0); p_lz = save_p_lz; @@ -1112,6 +1115,7 @@ ExpandInit(expand_T *xp) xp->xp_backslash = XP_BS_NONE; xp->xp_prefix = XP_PREFIX_NONE; xp->xp_numfiles = -1; + VIM_CLEAR(cmdline_orig); } /* @@ -1238,6 +1242,10 @@ showmatches(expand_T *xp, int wildmenu UNUSED) int attr; int showtail; + // Save cmdline before expansion + if (ccline->cmdbuff != NULL) + cmdline_orig = vim_strnsave(ccline->cmdbuff, ccline->cmdlen); + if (xp->xp_numfiles == -1) { set_expand_context(xp); @@ -4299,4 +4307,36 @@ f_getcompletion(typval_T *argvars, typval_T *rettv) vim_free(pat); ExpandCleanup(&xpc); } + +/* + * "cmdcomplete_info()" function + */ + void +f_cmdcomplete_info(typval_T *argvars UNUSED, typval_T *rettv) +{ + cmdline_info_T *ccline = get_cmdline_info(); + dict_T *retdict; + list_T *li; + int idx; + int ret = OK; + + if (rettv_dict_alloc(rettv) == FAIL || ccline == NULL + || ccline->xpc == NULL || ccline->xpc->xp_files == NULL) + return; + retdict = rettv->vval.v_dict; + ret = dict_add_string(retdict, "cmdline_orig", cmdline_orig); + if (ret == OK) + ret = dict_add_number(retdict, "pum_visible", pum_visible()); + if (ret == OK) + ret = dict_add_number(retdict, "selected", ccline->xpc->xp_selected); + if (ret == OK) + { + li = list_alloc(); + if (li == NULL) + return; + ret = dict_add_list(retdict, "matches", li); + for (idx = 0; ret == OK && idx < ccline->xpc->xp_numfiles; idx++) + list_append_string(li, ccline->xpc->xp_files[idx], -1); + } +} #endif // FEAT_EVAL diff --git a/src/evalfunc.c b/src/evalfunc.c index 2aa516dc4..39f6aa9ab 100644 --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -2092,6 +2092,8 @@ static funcentry_T global_functions[] = ret_number, f_cindent}, {"clearmatches", 0, 1, FEARG_1, arg1_number, ret_void, f_clearmatches}, + {"cmdcomplete_info",0, 0, 0, NULL, + ret_dict_any, f_cmdcomplete_info}, {"col", 1, 2, FEARG_1, arg2_string_or_list_number, ret_number, f_col}, {"complete", 2, 2, FEARG_2, arg2_number_list, diff --git a/src/ex_getln.c b/src/ex_getln.c index c4b0a0095..1137708ae 100644 --- a/src/ex_getln.c +++ b/src/ex_getln.c @@ -1915,6 +1915,11 @@ getcmdline_int( } } + // Trigger CmdlineLeavePre autocommand + if (ccline.cmdfirstc != NUL && (c == ' ' || c == ' ' || c == K_KENTER + || c == ESC || c == Ctrl_C)) + trigger_cmd_autocmd(cmdline_type, EVENT_CMDLINELEAVEPRE); + // The wildmenu is cleared if the pressed key is not used for // navigating the wild menu (i.e. the key is not 'wildchar' or // 'wildcharm' or Ctrl-N or Ctrl-P or Ctrl-A or Ctrl-L). diff --git a/src/proto/cmdexpand.pro b/src/proto/cmdexpand.pro index e627639d9..73db378bf 100644 --- a/src/proto/cmdexpand.pro +++ b/src/proto/cmdexpand.pro @@ -23,4 +23,5 @@ int wildmenu_translate_key(cmdline_info_T *cclp, int key, expand_T *xp, int did_ int wildmenu_process_key(cmdline_info_T *cclp, int key, expand_T *xp); void wildmenu_cleanup(cmdline_info_T *cclp); void f_getcompletion(typval_T *argvars, typval_T *rettv); +void f_cmdcomplete_info(typval_T *argvars UNUSED, typval_T *rettv); /* vim: set ft=c : */ diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim index 24a5f6138..ae587117e 100644 --- a/src/testdir/test_autocmd.vim +++ b/src/testdir/test_autocmd.vim @@ -2000,6 +2000,47 @@ func Test_QuitPre() bwipe Xbar endfunc +func Test_Cmdline_Trigger() + autocmd CmdlineLeavePre : let g:log = "CmdlineLeavePre" + new + let g:log = '' + nnoremap <F1> <Cmd>echo "hello"<CR> + call feedkeys("\<F1>", 'x') + call assert_equal('', g:log) + nunmap <F1> + let g:log = '' + nnoremap <F1> :echo "hello"<CR> + call feedkeys("\<F1>", 'x') + call assert_equal('CmdlineLeavePre', g:log) + nunmap <F1> + let g:log = '' + split + call assert_equal('', g:log) + call feedkeys(":echo hello", "tx") + call assert_equal('CmdlineLeavePre', g:log) + let g:log = '' + close + call assert_equal('', g:log) + call feedkeys(":echo hello", "tx") + call assert_equal('CmdlineLeavePre', g:log) + let g:log = '' + tabnew + call assert_equal('', g:log) + call feedkeys(":echo hello", "tx") + call assert_equal('CmdlineLeavePre', g:log) + let g:log = '' + split + call assert_equal('', g:log) + call feedkeys(":echo hello", "tx") + call assert_equal('CmdlineLeavePre', g:log) + let g:log = '' + tabclose + call assert_equal('', g:log) + call feedkeys(":echo hello", "tx") + call assert_equal('CmdlineLeavePre', g:log) + bw! +endfunc + func Test_Cmdline() au! CmdlineChanged : let g:text = getcmdline() let g:text = 0 @@ -2073,30 +2114,54 @@ func Test_Cmdline() au! CmdlineEnter : let g:entered = expand('<afile>') au! CmdlineLeave : let g:left = expand('<afile>') + au! CmdlineLeavePre : let g:leftpre = expand('<afile>') let g:entered = 0 let g:left = 0 + let g:leftpre = 0 call feedkeys(":echo 'hello'\<CR>", 'xt') call assert_equal(':', g:entered) call assert_equal(':', g:left) + call assert_equal(':', g:leftpre) au! CmdlineEnter au! CmdlineLeave + au! CmdlineLeavePre let save_shellslash = &shellslash set noshellslash au! CmdlineEnter / let g:entered = expand('<afile>') au! CmdlineLeave / let g:left = expand('<afile>') + au! CmdlineLeavePre / let g:leftpre = expand('<afile>') let g:entered = 0 let g:left = 0 + let g:leftpre = 0 new call setline(1, 'hello') call feedkeys("/hello\<CR>", 'xt') call assert_equal('/', g:entered) call assert_equal('/', g:left) + call assert_equal('/', g:leftpre) bwipe! au! CmdlineEnter au! CmdlineLeave + au! CmdlineLeavePre let &shellslash = save_shellslash + let g:left = "cancelled" + let g:leftpre = "cancelled" + au! CmdlineLeave : let g:left = "triggered" + au! CmdlineLeavePre : let g:leftpre = "triggered" + call feedkeys(":echo 'hello'\<esc>", 'xt') + call assert_equal('triggered', g:left) + call assert_equal('triggered', g:leftpre) + let g:left = "cancelled" + let g:leftpre = "cancelled" + au! CmdlineLeave : let g:left = "triggered" + call feedkeys(":echo 'hello'\<c-c>", 'xt') + call assert_equal('triggered', g:left) + call assert_equal('triggered', g:leftpre) + au! CmdlineLeave + au! CmdlineLeavePre + au! CursorMovedC : let g:pos += [getcmdpos()] let g:pos = [] call feedkeys(":foo bar baz\<C-W>\<C-W>\<C-W>\<Esc>", 'xt') diff --git a/src/testdir/test_cmdline.vim b/src/testdir/test_cmdline.vim index 57b57cb8d..364909cc5 100644 --- a/src/testdir/test_cmdline.vim +++ b/src/testdir/test_cmdline.vim @@ -4268,4 +4268,48 @@ func Test_cd_bslash_completion_windows() let &shellslash = save_shellslash endfunc +" Testg cmdcomplete_info() with CmdlineLeavePre autocmd +func Test_cmdcomplete_info() + augroup test_CmdlineLeavePre + autocmd! + autocmd CmdlineLeavePre * let g:cmdcomplete_info = string(cmdcomplete_info()) + augroup END + new + 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& +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/version.c b/src/version.c index 40cff483e..60c524385 100644 --- a/src/version.c +++ b/src/version.c @@ -704,6 +704,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1329, /**/ 1328, /**/ diff --git a/src/vim.h b/src/vim.h index 29c3cb888..41984dadc 100644 --- a/src/vim.h +++ b/src/vim.h @@ -1371,6 +1371,7 @@ enum auto_event EVENT_BUFWRITEPRE, // before writing a buffer EVENT_CMDLINECHANGED, // command line was modified EVENT_CMDLINEENTER, // after entering the command line + EVENT_CMDLINELEAVEPRE, // just before leaving the command line EVENT_CMDLINELEAVE, // before leaving the command line EVENT_CMDUNDEFINED, // command undefined EVENT_CMDWINENTER, // after entering the cmdline window -- -- 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 vim_dev+unsubscr...@googlegroups.com. To view this discussion visit https://groups.google.com/d/msgid/vim_dev/E1u6nTZ-00GGUw-2B%40256bit.org.