diff options
author | zeertzjq <zeertzjq@outlook.com> | 2023-01-17 14:35:05 +0800 |
---|---|---|
committer | zeertzjq <zeertzjq@outlook.com> | 2023-01-17 15:55:58 +0800 |
commit | 441d13eae5569be2856a8d17b87f0897b85f4ad8 (patch) | |
tree | 2562dddfa8bb2ac2fd7a3638fa817ac1ca1b9d71 | |
parent | 2093e574c6c934a718f96d0a173aa965d3958a8b (diff) | |
download | rneovim-441d13eae5569be2856a8d17b87f0897b85f4ad8.tar.gz rneovim-441d13eae5569be2856a8d17b87f0897b85f4ad8.tar.bz2 rneovim-441d13eae5569be2856a8d17b87f0897b85f4ad8.zip |
vim-patch:8.2.4482: no fuzzy cmdline completion for user defined completion
Problem: No fuzzy cmdline completion for user defined completion.
Solution: Add fuzzy completion for user defined completion. (Yegappan
Lakshmanan, closes vim/vim#9858)
https://github.com/vim/vim/commit/afd4ae35d66b2e7732eceb5ad9f6b4ece6b7c64c
Cherry-pick related docs from Vim runtime.
N/A patches for version.c:
vim-patch:8.2.4485: compiler warning for uninitialized variable
vim-patch:8.2.4732: duplicate code to free fuzzy matches
Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
-rw-r--r-- | runtime/doc/map.txt | 8 | ||||
-rw-r--r-- | runtime/doc/options.txt | 2 | ||||
-rw-r--r-- | src/nvim/cmdexpand.c | 84 | ||||
-rw-r--r-- | src/nvim/testdir/test_cmdline.vim | 357 |
4 files changed, 308 insertions, 143 deletions
diff --git a/runtime/doc/map.txt b/runtime/doc/map.txt index ccd48a8959..cb8b162eb6 100644 --- a/runtime/doc/map.txt +++ b/runtime/doc/map.txt @@ -1432,9 +1432,11 @@ The function arguments are: The function may use these for determining context. For the "custom" argument, it is not necessary to filter candidates against the (implicit pattern in) ArgLead. Vim will filter the candidates with its regexp engine -after function return, and this is probably more efficient in most cases. For -the "customlist" argument, Vim will not filter the returned completion -candidates and the user supplied function should filter the candidates. +after function return, and this is probably more efficient in most cases. If +'wildoptions' contains "fuzzy", then the candidates will be filtered using +|fuzzy-matching|. For the "customlist" argument, Vim will not +filter the returned completion candidates and the user supplied function +should filter the candidates. The following example lists user names to a Finger command > :com -complete=custom,ListUsers -nargs=1 Finger !finger <args> diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index 0683bb0602..169ec95b03 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -7126,7 +7126,7 @@ A jump table for the options with a short description can be found at |Q_op|. global A list of words that change how |cmdline-completion| is done. The following values are supported: - fuzzy Use fuzzy matching to find completion matches. When + fuzzy Use |fuzzy-matching| to find completion matches. When this value is specified, wildcard expansion will not be used for completion. The matches will be sorted by the "best match" rather than alphabetically sorted. diff --git a/src/nvim/cmdexpand.c b/src/nvim/cmdexpand.c index 4559e83e20..0d291881ba 100644 --- a/src/nvim/cmdexpand.c +++ b/src/nvim/cmdexpand.c @@ -111,12 +111,12 @@ static bool cmdline_fuzzy_completion_supported(const expand_T *const xp) && xp->xp_context != EXPAND_SHELLCMD && xp->xp_context != EXPAND_TAGS && xp->xp_context != EXPAND_TAGS_LISTFILES - && xp->xp_context != EXPAND_USER_DEFINED && xp->xp_context != EXPAND_USER_LIST; } /// Returns true if fuzzy completion for cmdline completion is enabled and -/// "fuzzystr" is not empty. +/// "fuzzystr" is not empty. If search pattern is empty, then don't use fuzzy +/// matching. bool cmdline_fuzzy_complete(const char *const fuzzystr) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE { @@ -2585,16 +2585,10 @@ static int ExpandOther(char *pat, expand_T *xp, regmatch_T *rmp, char ***matches // right function to do the expansion. for (int i = 0; i < (int)ARRAY_SIZE(tab); i++) { if (xp->xp_context == tab[i].context) { - // Use fuzzy matching if 'wildoptions' has "fuzzy". - // If no search pattern is supplied, then don't use fuzzy - // matching and return all the found items. - const bool fuzzy = cmdline_fuzzy_complete(pat); - if (tab[i].ic) { rmp->rm_ic = true; } - ExpandGeneric(xp, rmp, matches, numMatches, tab[i].func, tab[i].escaped, - fuzzy ? pat : NULL); + ExpandGeneric(pat, xp, rmp, matches, numMatches, tab[i].func, tab[i].escaped); ret = OK; break; } @@ -2735,7 +2729,7 @@ static int ExpandFromContext(expand_T *xp, char *pat, char ***matches, int *numM } else if (xp->xp_context == EXPAND_MAPPINGS) { ret = ExpandMappings(pat, ®match, numMatches, matches); } else if (xp->xp_context == EXPAND_USER_DEFINED) { - ret = ExpandUserDefined(xp, ®match, matches, numMatches); + ret = ExpandUserDefined(pat, xp, ®match, matches, numMatches); } else { ret = ExpandOther(pat, xp, ®match, matches, numMatches); } @@ -2754,17 +2748,16 @@ static int ExpandFromContext(expand_T *xp, char *pat, char ***matches, int *numM /// obtain strings, one by one. The strings are matched against a regexp /// program. Matching strings are copied into an array, which is returned. /// -/// If "fuzzystr" is not NULL, then fuzzy matching is used. Otherwise, -/// regex matching is used. -/// /// @param func returns a string from the list -static void ExpandGeneric(expand_T *xp, regmatch_T *regmatch, char ***matches, int *numMatches, - CompleteListItemGetter func, int escaped, const char *const fuzzystr) +static void ExpandGeneric(const char *const pat, expand_T *xp, regmatch_T *regmatch, + char ***matches, int *numMatches, CompleteListItemGetter func, + int escaped) { int i; size_t count = 0; char *str; - const bool fuzzy = fuzzystr != NULL; + + const bool fuzzy = cmdline_fuzzy_complete(pat); // count the number of matching names for (i = 0;; i++) { @@ -2780,7 +2773,7 @@ static void ExpandGeneric(expand_T *xp, regmatch_T *regmatch, char ***matches, i if (!fuzzy) { match = vim_regexec(regmatch, str, (colnr_T)0); } else { - match = fuzzy_match_str(str, fuzzystr) != 0; + match = fuzzy_match_str(str, pat) != 0; } if (match) { count++; @@ -2814,9 +2807,10 @@ static void ExpandGeneric(expand_T *xp, regmatch_T *regmatch, char ***matches, i if (!fuzzy) { match = vim_regexec(regmatch, str, (colnr_T)0); } else { - score = fuzzy_match_str(str, fuzzystr); + score = fuzzy_match_str(str, pat); match = (score != 0); } + if (!match) { continue; } @@ -3044,12 +3038,16 @@ static void *call_user_expand_func(user_expand_func_T user_expand_func, expand_T return ret; } -/// Expand names with a function defined by the user. -static int ExpandUserDefined(expand_T *xp, regmatch_T *regmatch, char ***matches, int *numMatches) +/// Expand names with a function defined by the user (EXPAND_USER_DEFINED and +/// EXPAND_USER_LIST). +static int ExpandUserDefined(const char *const pat, expand_T *xp, regmatch_T *regmatch, + char ***matches, int *numMatches) { char *e; garray_T ga; + const bool fuzzy = cmdline_fuzzy_complete(pat); + *matches = NULL; *numMatches = 0; char *const retstr = call_user_expand_func((user_expand_func_T)call_func_retstr, xp); @@ -3058,7 +3056,13 @@ static int ExpandUserDefined(expand_T *xp, regmatch_T *regmatch, char ***matches return FAIL; } - ga_init(&ga, (int)sizeof(char *), 3); + if (!fuzzy) { + ga_init(&ga, (int)sizeof(char *), 3); + } else { + ga_init(&ga, (int)sizeof(fuzmatch_str_T), 3); + } + + int count = 0; for (char *s = retstr; *s != NUL; s = e) { e = vim_strchr(s, '\n'); if (e == NULL) { @@ -3067,10 +3071,32 @@ static int ExpandUserDefined(expand_T *xp, regmatch_T *regmatch, char ***matches const char keep = *e; *e = NUL; - const bool skip = xp->xp_pattern[0] && vim_regexec(regmatch, s, (colnr_T)0) == 0; + bool match; + int score = 0; + if (xp->xp_pattern[0] || fuzzy) { + if (!fuzzy) { + match = vim_regexec(regmatch, s, (colnr_T)0); + } else { + score = fuzzy_match_str(s, pat); + match = (score != 0); + } + } else { + match = true; // match everything + } + *e = keep; - if (!skip) { - GA_APPEND(char *, &ga, xstrnsave(s, (size_t)(e - s))); + + if (match) { + if (!fuzzy) { + GA_APPEND(char *, &ga, xstrnsave(s, (size_t)(e - s))); + } else { + GA_APPEND(fuzmatch_str_T, &ga, ((fuzmatch_str_T){ + .idx = count, + .str = xstrnsave(s, (size_t)(e - s)), + .score = score, + })); + } + count++; } if (*e != NUL) { @@ -3078,8 +3104,14 @@ static int ExpandUserDefined(expand_T *xp, regmatch_T *regmatch, char ***matches } } xfree(retstr); - *matches = ga.ga_data; - *numMatches = ga.ga_len; + + if (!fuzzy) { + *matches = ga.ga_data; + *numMatches = ga.ga_len; + } else { + fuzzymatches_to_strmatches(ga.ga_data, matches, count, false); + *numMatches = count; + } return OK; } diff --git a/src/nvim/testdir/test_cmdline.vim b/src/nvim/testdir/test_cmdline.vim index f5c84e0729..20e8214692 100644 --- a/src/nvim/testdir/test_cmdline.vim +++ b/src/nvim/testdir/test_cmdline.vim @@ -2670,9 +2670,8 @@ func Test_cmdline_complete_dlist() call assert_equal("\"dlist 10 /pat/ | chistory", @:) endfunc -" Test for 'fuzzy' in 'wildoptions' (fuzzy completion) -func Test_wildoptions_fuzzy() - " argument list (only for :argdel) +" argument list (only for :argdel) fuzzy completion +func Test_fuzzy_completion_arglist() argadd change.py count.py charge.py set wildoptions& call feedkeys(":argdel cge\<C-A>\<C-B>\"\<CR>", 'tx') @@ -2681,8 +2680,11 @@ func Test_wildoptions_fuzzy() call feedkeys(":argdel cge\<C-A>\<C-B>\"\<CR>", 'tx') call assert_equal('"argdel change.py charge.py', @:) %argdelete + set wildoptions& +endfunc - " autocmd group name fuzzy completion +" autocmd group name fuzzy completion +func Test_fuzzy_completion_autocmd() set wildoptions& augroup MyFuzzyGroup augroup END @@ -2696,8 +2698,11 @@ func Test_wildoptions_fuzzy() call feedkeys(":augroup My*p\<Tab>\<C-B>\"\<CR>", 'tx') call assert_equal('"augroup My*p', @:) augroup! MyFuzzyGroup + set wildoptions& +endfunc - " buffer name fuzzy completion +" buffer name fuzzy completion +func Test_fuzzy_completion_bufname() set wildoptions& edit SomeFile.txt enew @@ -2711,24 +2716,29 @@ func Test_wildoptions_fuzzy() call feedkeys(":b S*File.txt\<Tab>\<C-B>\"\<CR>", 'tx') call assert_equal('"b S*File.txt', @:) %bw! + set wildoptions& +endfunc - " buffer name (full path) fuzzy completion - if has('unix') - set wildoptions& - call mkdir('Xcmd/Xstate/Xfile.js', 'p') - edit Xcmd/Xstate/Xfile.js - cd Xcmd/Xstate - enew - call feedkeys(":b CmdStateFile\<Tab>\<C-B>\"\<CR>", 'tx') - call assert_equal('"b CmdStateFile', @:) - set wildoptions=fuzzy - call feedkeys(":b CmdStateFile\<Tab>\<C-B>\"\<CR>", 'tx') - call assert_match('Xcmd/Xstate/Xfile.js$', @:) - cd - - call delete('Xcmd', 'rf') - endif +" buffer name (full path) fuzzy completion +func Test_fuzzy_completion_bufname_fullpath() + CheckUnix + set wildoptions& + call mkdir('Xcmd/Xstate/Xfile.js', 'p') + edit Xcmd/Xstate/Xfile.js + cd Xcmd/Xstate + enew + call feedkeys(":b CmdStateFile\<Tab>\<C-B>\"\<CR>", 'tx') + call assert_equal('"b CmdStateFile', @:) + set wildoptions=fuzzy + call feedkeys(":b CmdStateFile\<Tab>\<C-B>\"\<CR>", 'tx') + call assert_match('Xcmd/Xstate/Xfile.js$', @:) + cd - + call delete('Xcmd', 'rf') + set wildoptions& +endfunc - " :behave suboptions fuzzy completion +" :behave suboptions fuzzy completion +func Test_fuzzy_completion_behave() set wildoptions& call feedkeys(":behave xm\<Tab>\<C-B>\"\<CR>", 'tx') call assert_equal('"behave xm', @:) @@ -2743,10 +2753,15 @@ func Test_wildoptions_fuzzy() call feedkeys(":behave win\<C-D>\<F4>\<C-B>\"\<CR>", 'tx') call assert_equal('mswin', g:Sline) call assert_equal('"behave win', @:) + set wildoptions& +endfunc - " colorscheme name fuzzy completion - NOT supported +" " colorscheme name fuzzy completion - NOT supported +" func Test_fuzzy_completion_colorscheme() +" endfunc - " built-in command name fuzzy completion +" built-in command name fuzzy completion +func Test_fuzzy_completion_cmdname() set wildoptions& call feedkeys(":sbwin\<Tab>\<C-B>\"\<CR>", 'tx') call assert_equal('"sbwin', @:) @@ -2757,24 +2772,31 @@ func Test_wildoptions_fuzzy() call assert_equal('"sbrewind', @:) call feedkeys(":sbr*d\<Tab>\<C-B>\"\<CR>", 'tx') call assert_equal('"sbr*d', @:) + set wildoptions& +endfunc - " compiler name fuzzy completion - NOT supported +" " compiler name fuzzy completion - NOT supported +" func Test_fuzzy_completion_compiler() +" endfunc - " :cscope suboptions fuzzy completion - if has('cscope') - set wildoptions& - call feedkeys(":cscope ret\<Tab>\<C-B>\"\<CR>", 'tx') - call assert_equal('"cscope ret', @:) - call feedkeys(":cscope re*t\<Tab>\<C-B>\"\<CR>", 'tx') - call assert_equal('"cscope reset', @:) - set wildoptions=fuzzy - call feedkeys(":cscope ret\<Tab>\<C-B>\"\<CR>", 'tx') - call assert_equal('"cscope reset', @:) - call feedkeys(":cscope re*t\<Tab>\<C-B>\"\<CR>", 'tx') - call assert_equal('"cscope re*t', @:) - endif +" :cscope suboptions fuzzy completion +func Test_fuzzy_completion_cscope() + CheckFeature cscope + set wildoptions& + call feedkeys(":cscope ret\<Tab>\<C-B>\"\<CR>", 'tx') + call assert_equal('"cscope ret', @:) + call feedkeys(":cscope re*t\<Tab>\<C-B>\"\<CR>", 'tx') + call assert_equal('"cscope reset', @:) + set wildoptions=fuzzy + call feedkeys(":cscope ret\<Tab>\<C-B>\"\<CR>", 'tx') + call assert_equal('"cscope reset', @:) + call feedkeys(":cscope re*t\<Tab>\<C-B>\"\<CR>", 'tx') + call assert_equal('"cscope re*t', @:) + set wildoptions& +endfunc - " :diffget/:diffput buffer name fuzzy completion +" :diffget/:diffput buffer name fuzzy completion +func Test_fuzzy_completion_diff() new SomeBuffer diffthis new OtherBuffer @@ -2790,26 +2812,37 @@ func Test_wildoptions_fuzzy() call feedkeys(":diffput sbuf\<Tab>\<C-B>\"\<CR>", 'tx') call assert_equal('"diffput SomeBuffer', @:) %bw! + set wildoptions& +endfunc - " directory name fuzzy completion - NOT supported +" " directory name fuzzy completion - NOT supported +" func Test_fuzzy_completion_dirname() +" endfunc - " environment variable name fuzzy completion +" environment variable name fuzzy completion +func Test_fuzzy_completion_env() set wildoptions& call feedkeys(":echo $VUT\<Tab>\<C-B>\"\<CR>", 'tx') call assert_equal('"echo $VUT', @:) set wildoptions=fuzzy call feedkeys(":echo $VUT\<Tab>\<C-B>\"\<CR>", 'tx') call assert_equal('"echo $VIMRUNTIME', @:) + set wildoptions& +endfunc - " autocmd event fuzzy completion +" autocmd event fuzzy completion +func Test_fuzzy_completion_autocmd_event() set wildoptions& call feedkeys(":autocmd BWout\<Tab>\<C-B>\"\<CR>", 'tx') call assert_equal('"autocmd BWout', @:) set wildoptions=fuzzy call feedkeys(":autocmd BWout\<Tab>\<C-B>\"\<CR>", 'tx') call assert_equal('"autocmd BufWipeout', @:) + set wildoptions& +endfunc - " vim expression fuzzy completion +" vim expression fuzzy completion +func Test_fuzzy_completion_expr() let g:PerPlaceCount = 10 set wildoptions& call feedkeys(":let c = ppc\<Tab>\<C-B>\"\<CR>", 'tx') @@ -2817,32 +2850,49 @@ func Test_wildoptions_fuzzy() set wildoptions=fuzzy call feedkeys(":let c = ppc\<Tab>\<C-B>\"\<CR>", 'tx') call assert_equal('"let c = PerPlaceCount', @:) + set wildoptions& +endfunc - " file name fuzzy completion - NOT supported +" " file name fuzzy completion - NOT supported +" func Test_fuzzy_completion_filename() +" endfunc - " files in path fuzzy completion - NOT supported +" " files in path fuzzy completion - NOT supported +" func Test_fuzzy_completion_filesinpath() +" endfunc - " filetype name fuzzy completion - NOT supported +" " filetype name fuzzy completion - NOT supported +" func Test_fuzzy_completion_filetype() +" endfunc - " user defined function name completion +" user defined function name completion +func Test_fuzzy_completion_userdefined_func() set wildoptions& - call feedkeys(":call Test_w_fuz\<Tab>\<C-B>\"\<CR>", 'tx') - call assert_equal('"call Test_w_fuz', @:) + call feedkeys(":call Test_f_u_f\<Tab>\<C-B>\"\<CR>", 'tx') + call assert_equal('"call Test_f_u_f', @:) set wildoptions=fuzzy - call feedkeys(":call Test_w_fuz\<Tab>\<C-B>\"\<CR>", 'tx') - call assert_equal('"call Test_wildoptions_fuzzy()', @:) + call feedkeys(":call Test_f_u_f\<Tab>\<C-B>\"\<CR>", 'tx') + call assert_equal('"call Test_fuzzy_completion_userdefined_func()', @:) + set wildoptions& +endfunc - " user defined command name completion +" user defined command name completion +func Test_fuzzy_completion_userdefined_cmd() set wildoptions& call feedkeys(":MsFeat\<Tab>\<C-B>\"\<CR>", 'tx') call assert_equal('"MsFeat', @:) set wildoptions=fuzzy call feedkeys(":MsFeat\<Tab>\<C-B>\"\<CR>", 'tx') call assert_equal('"MissingFeature', @:) + set wildoptions& +endfunc - " :help tag fuzzy completion - NOT supported +" " :help tag fuzzy completion - NOT supported +" func Test_fuzzy_completion_helptag() +" endfunc - " highlight group name fuzzy completion +" highlight group name fuzzy completion +func Test_fuzzy_completion_hlgroup() set wildoptions& call feedkeys(":highlight SKey\<Tab>\<C-B>\"\<CR>", 'tx') call assert_equal('"highlight SKey', @:) @@ -2853,8 +2903,11 @@ func Test_wildoptions_fuzzy() call assert_equal('"highlight SpecialKey', @:) call feedkeys(":highlight Sp*Key\<Tab>\<C-B>\"\<CR>", 'tx') call assert_equal('"highlight Sp*Key', @:) + set wildoptions& +endfunc - " :history suboptions fuzzy completion +" :history suboptions fuzzy completion +func Test_fuzzy_completion_history() set wildoptions& call feedkeys(":history dg\<Tab>\<C-B>\"\<CR>", 'tx') call assert_equal('"history dg', @:) @@ -2865,26 +2918,34 @@ func Test_wildoptions_fuzzy() call assert_equal('"history debug', @:) call feedkeys(":history se*h\<Tab>\<C-B>\"\<CR>", 'tx') call assert_equal('"history se*h', @:) + set wildoptions& +endfunc - " :language locale name fuzzy completion - if has('unix') - set wildoptions& - call feedkeys(":lang psx\<Tab>\<C-B>\"\<CR>", 'tx') - call assert_equal('"lang psx', @:) - set wildoptions=fuzzy - call feedkeys(":lang psx\<Tab>\<C-B>\"\<CR>", 'tx') - call assert_equal('"lang POSIX', @:) - endif +" :language locale name fuzzy completion +func Test_fuzzy_completion_lang() + CheckUnix + set wildoptions& + call feedkeys(":lang psx\<Tab>\<C-B>\"\<CR>", 'tx') + call assert_equal('"lang psx', @:) + set wildoptions=fuzzy + call feedkeys(":lang psx\<Tab>\<C-B>\"\<CR>", 'tx') + call assert_equal('"lang POSIX', @:) + set wildoptions& +endfunc - " :mapclear buffer argument fuzzy completion +" :mapclear buffer argument fuzzy completion +func Test_fuzzy_completion_mapclear() set wildoptions& call feedkeys(":mapclear buf\<Tab>\<C-B>\"\<CR>", 'tx') call assert_equal('"mapclear buf', @:) set wildoptions=fuzzy call feedkeys(":mapclear buf\<Tab>\<C-B>\"\<CR>", 'tx') call assert_equal('"mapclear <buffer>', @:) + set wildoptions& +endfunc - " map name fuzzy completion +" map name fuzzy completion +func Test_fuzzy_completion_mapname() " test regex completion works set wildoptions=fuzzy call feedkeys(":cnoremap <ex\<Tab> <esc> \<Tab>\<C-B>\"\<CR>", 'tx') @@ -2919,8 +2980,11 @@ func Test_wildoptions_fuzzy() nunmap <Plug>fendoff nunmap <Plug>state nunmap <Plug>FendingOff + set wildoptions& +endfunc - " abbreviation fuzzy completion +" abbreviation fuzzy completion +func Test_fuzzy_completion_abbr() set wildoptions=fuzzy call feedkeys(":iabbr wait\<Tab>\<C-B>\"\<CR>", 'tx') call assert_equal("\"iabbr <nowait>", @:) @@ -2930,26 +2994,34 @@ func Test_wildoptions_fuzzy() call feedkeys(":iabbr a1z\<Tab>\<C-B>\"\<CR>", 'tx') call assert_equal("\"iabbr a1z\t", @:) iunabbrev WaitForCompletion + set wildoptions& +endfunc - " menu name fuzzy completion - if has('gui_running') - set wildoptions& - call feedkeys(":menu pup\<Tab>\<C-B>\"\<CR>", 'tx') - call assert_equal('"menu pup', @:) - set wildoptions=fuzzy - call feedkeys(":menu pup\<Tab>\<C-B>\"\<CR>", 'tx') - call assert_equal('"menu PopUp.', @:) - endif +" menu name fuzzy completion +func Test_fuzzy_completion_menu() + CheckGui + set wildoptions& + call feedkeys(":menu pup\<Tab>\<C-B>\"\<CR>", 'tx') + call assert_equal('"menu pup', @:) + set wildoptions=fuzzy + call feedkeys(":menu pup\<Tab>\<C-B>\"\<CR>", 'tx') + call assert_equal('"menu PopUp.', @:) + set wildoptions& +endfunc - " :messages suboptions fuzzy completion +" :messages suboptions fuzzy completion +func Test_fuzzy_completion_messages() set wildoptions& call feedkeys(":messages clr\<Tab>\<C-B>\"\<CR>", 'tx') call assert_equal('"messages clr', @:) set wildoptions=fuzzy call feedkeys(":messages clr\<Tab>\<C-B>\"\<CR>", 'tx') call assert_equal('"messages clear', @:) + set wildoptions& +endfunc - " :set option name fuzzy completion +" :set option name fuzzy completion +func Test_fuzzy_completion_option() set wildoptions& call feedkeys(":set brkopt\<Tab>\<C-B>\"\<CR>", 'tx') call assert_equal('"set brkopt', @:) @@ -2962,67 +3034,94 @@ func Test_wildoptions_fuzzy() set wildoptions=fuzzy call feedkeys(":set fixeol\<Tab>\<C-B>\"\<CR>", 'tx') call assert_equal('"set fixendofline', @:) + set wildoptions& +endfunc - " :set <term_option> - " Nvim does not support term options - " set wildoptions& - " call feedkeys(":set t_E\<Tab>\<C-B>\"\<CR>", 'tx') - " call assert_equal('"set t_EC', @:) - " call feedkeys(":set <t_E\<Tab>\<C-B>\"\<CR>", 'tx') - " call assert_equal('"set <t_EC>', @:) - " set wildoptions=fuzzy - " call feedkeys(":set t_E\<Tab>\<C-B>\"\<CR>", 'tx') - " call assert_equal('"set t_EC', @:) - " call feedkeys(":set <t_E\<Tab>\<C-B>\"\<CR>", 'tx') - " call assert_equal('"set <t_EC>', @:) +" :set <term_option> +func Test_fuzzy_completion_term_option() + throw 'Skipped: Nvim does not support term options' + set wildoptions& + call feedkeys(":set t_E\<Tab>\<C-B>\"\<CR>", 'tx') + call assert_equal('"set t_EC', @:) + call feedkeys(":set <t_E\<Tab>\<C-B>\"\<CR>", 'tx') + call assert_equal('"set <t_EC>', @:) + set wildoptions=fuzzy + call feedkeys(":set t_E\<Tab>\<C-B>\"\<CR>", 'tx') + call assert_equal('"set t_EC', @:) + call feedkeys(":set <t_E\<Tab>\<C-B>\"\<CR>", 'tx') + call assert_equal('"set <t_EC>', @:) + set wildoptions& +endfunc - " :packadd directory name fuzzy completion - NOT supported +" " :packadd directory name fuzzy completion - NOT supported +" func Test_fuzzy_completion_packadd() +" endfunc - " shell command name fuzzy completion - NOT supported +" " shell command name fuzzy completion - NOT supported +" func Test_fuzzy_completion_shellcmd() +" endfunc - " :sign suboptions fuzzy completion +" :sign suboptions fuzzy completion +func Test_fuzzy_completion_sign() set wildoptions& call feedkeys(":sign ufe\<Tab>\<C-B>\"\<CR>", 'tx') call assert_equal('"sign ufe', @:) set wildoptions=fuzzy call feedkeys(":sign ufe\<Tab>\<C-B>\"\<CR>", 'tx') call assert_equal('"sign undefine', @:) + set wildoptions& +endfunc - " :syntax suboptions fuzzy completion +" :syntax suboptions fuzzy completion +func Test_fuzzy_completion_syntax_cmd() set wildoptions& call feedkeys(":syntax kwd\<Tab>\<C-B>\"\<CR>", 'tx') call assert_equal('"syntax kwd', @:) set wildoptions=fuzzy call feedkeys(":syntax kwd\<Tab>\<C-B>\"\<CR>", 'tx') call assert_equal('"syntax keyword', @:) + set wildoptions& +endfunc - " syntax group name fuzzy completion +" syntax group name fuzzy completion +func Test_fuzzy_completion_syntax_group() set wildoptions& call feedkeys(":syntax list mpar\<Tab>\<C-B>\"\<CR>", 'tx') call assert_equal('"syntax list mpar', @:) set wildoptions=fuzzy call feedkeys(":syntax list mpar\<Tab>\<C-B>\"\<CR>", 'tx') - " Fuzzy match favours NvimParenthesis over MatchParen + " Fuzzy match prefers NvimParenthesis over MatchParen " call assert_equal('"syntax list MatchParen', @:) call assert_equal('"syntax list NvimParenthesis', @:) + set wildoptions& +endfunc - " :syntime suboptions fuzzy completion - if has('profile') - set wildoptions& - call feedkeys(":syntime clr\<Tab>\<C-B>\"\<CR>", 'tx') - call assert_equal('"syntime clr', @:) - set wildoptions=fuzzy - call feedkeys(":syntime clr\<Tab>\<C-B>\"\<CR>", 'tx') - call assert_equal('"syntime clear', @:) - endif +" :syntime suboptions fuzzy completion +func Test_fuzzy_completion_syntime() + CheckFeature profile + set wildoptions& + call feedkeys(":syntime clr\<Tab>\<C-B>\"\<CR>", 'tx') + call assert_equal('"syntime clr', @:) + set wildoptions=fuzzy + call feedkeys(":syntime clr\<Tab>\<C-B>\"\<CR>", 'tx') + call assert_equal('"syntime clear', @:) + set wildoptions& +endfunc - " tag name fuzzy completion - NOT supported +" " tag name fuzzy completion - NOT supported +" func Test_fuzzy_completion_tagname() +" endfunc - " tag name and file fuzzy completion - NOT supported +" " tag name and file fuzzy completion - NOT supported +" func Test_fuzzy_completion_tagfile() +" endfunc - " user names fuzzy completion - how to test this functionality? +" " user names fuzzy completion - how to test this functionality? +" func Test_fuzzy_completion_username() +" endfunc - " user defined variable name fuzzy completion +" user defined variable name fuzzy completion +func Test_fuzzy_completion_userdefined_var() let g:SomeVariable=10 set wildoptions& call feedkeys(":let SVar\<Tab>\<C-B>\"\<CR>", 'tx') @@ -3030,8 +3129,11 @@ func Test_wildoptions_fuzzy() set wildoptions=fuzzy call feedkeys(":let SVar\<Tab>\<C-B>\"\<CR>", 'tx') call assert_equal('"let SomeVariable', @:) + set wildoptions& +endfunc - " Test for sorting the results by the best match +" Test for sorting the results by the best match +func Test_fuzzy_completion_cmd_sort_results() %bw! command T123format : command T123goformat : @@ -3049,9 +3151,11 @@ func Test_wildoptions_fuzzy() delcommand T123state delcommand T123FendingOff %bw + set wildoptions& +endfunc - " Test for fuzzy completion of a command with lower case letters and a - " number +" Test for fuzzy completion of a command with lower case letters and a number +func Test_fuzzy_completion_cmd_alnum() command Foo2Bar : set wildoptions=fuzzy call feedkeys(":foo2\<Tab>\<C-B>\"\<CR>", 'tx') @@ -3061,8 +3165,11 @@ func Test_wildoptions_fuzzy() call feedkeys(":bar\<Tab>\<C-B>\"\<CR>", 'tx') call assert_equal('"Foo2Bar', @:) delcommand Foo2Bar + set wildoptions& +endfunc - " Test for command completion for a command starting with 'k' +" Test for command completion for a command starting with 'k' +func Test_fuzzy_completion_cmd_k() command KillKillKill : set wildoptions& call feedkeys(":killkill\<Tab>\<C-B>\"\<CR>", 'tx') @@ -3071,9 +3178,33 @@ func Test_wildoptions_fuzzy() call feedkeys(":killkill\<Tab>\<C-B>\"\<CR>", 'tx') call assert_equal('"KillKillKill', @:) delcom KillKillKill + set wildoptions& +endfunc +" Test for fuzzy completion for user defined custom completion function +func Test_fuzzy_completion_custom_func() + func Tcompl(a, c, p) + return "format\ngoformat\nTestFOrmat\nfendoff\nstate" + endfunc + command -nargs=* -complete=custom,Tcompl Fuzzy : + set wildoptions& + call feedkeys(":Fuzzy fo\<C-A>\<C-B>\"\<CR>", 'tx') + call assert_equal("\"Fuzzy format", @:) + call feedkeys(":Fuzzy xy\<Tab>\<C-B>\"\<CR>", 'tx') + call assert_equal("\"Fuzzy xy", @:) + call feedkeys(":Fuzzy ttt\<C-A>\<C-B>\"\<CR>", 'tx') + call assert_equal("\"Fuzzy ttt", @:) + set wildoptions=fuzzy + call feedkeys(":Fuzzy \<C-A>\<C-B>\"\<CR>", 'tx') + call assert_equal("\"Fuzzy format goformat TestFOrmat fendoff state", @:) + call feedkeys(":Fuzzy fo\<C-A>\<C-B>\"\<CR>", 'tx') + call assert_equal("\"Fuzzy format TestFOrmat goformat fendoff", @:) + call feedkeys(":Fuzzy xy\<Tab>\<C-B>\"\<CR>", 'tx') + call assert_equal("\"Fuzzy xy", @:) + call feedkeys(":Fuzzy ttt\<C-A>\<C-B>\"\<CR>", 'tx') + call assert_equal("\"Fuzzy TestFOrmat", @:) + delcom Fuzzy set wildoptions& - %bw! endfunc " Test for :breakadd argument completion |