mirror of
https://github.com/vim/vim.git
synced 2026-05-28 00:21:37 +02:00
patch 9.2.0451: 'findfunc' can't return extra info for cmdline completion
Problem: 'findfunc' can't return extra info for cmdline completion
(Maxim Kim).
Solution: Handle 'findfunc' return value in cmdline completion like that
of "customlist" functions (zeertzjq).
fixes: #20155
closes: #20158
Signed-off-by: zeertzjq <zeertzjq@outlook.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
committed by
Christian Brabandt
parent
9299332917
commit
58124789aa
@@ -1,4 +1,4 @@
|
||||
*options.txt* For Vim version 9.2. Last change: 2026 May 04
|
||||
*options.txt* For Vim version 9.2. Last change: 2026 May 07
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -3983,7 +3983,9 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
|String| and is the |:find| command argument. The second argument is
|
||||
a |Boolean| and is set to |v:true| when the function is called to get
|
||||
a List of command-line completion matches for the |:find| command.
|
||||
The function should return a List of strings.
|
||||
The function should return a List of strings, or, in the command-line
|
||||
completion case, whatever a |:command-completion-customlist| function
|
||||
may return.
|
||||
|
||||
The function is called only once per |:find| command invocation.
|
||||
The function can process all the directories specified in 'path'.
|
||||
|
||||
+28
-17
@@ -3156,7 +3156,7 @@ expand_files_and_dirs(
|
||||
if (xp->xp_context == EXPAND_FINDFUNC)
|
||||
{
|
||||
#ifdef FEAT_EVAL
|
||||
ret = expand_findfunc(pat, matches, numMatches);
|
||||
ret = expand_findfunc(xp, pat, matches, numMatches);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
@@ -4148,16 +4148,13 @@ ExpandUserDefined(
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Expand names with a list returned by a function defined by the user.
|
||||
*/
|
||||
static int
|
||||
ExpandUserList(
|
||||
expand_T *xp,
|
||||
void
|
||||
expand_process_user_list(
|
||||
list_T *retlist,
|
||||
char_u ***matches,
|
||||
int *numMatches)
|
||||
int *numMatches,
|
||||
expand_T *xp)
|
||||
{
|
||||
list_T *retlist;
|
||||
listitem_T *li;
|
||||
garray_T ga;
|
||||
garray_T ga_abbr;
|
||||
@@ -4167,12 +4164,6 @@ ExpandUserList(
|
||||
int have_extra = FALSE;
|
||||
int i;
|
||||
|
||||
*matches = NULL;
|
||||
*numMatches = 0;
|
||||
retlist = call_user_expand_func(call_func_retlist, xp);
|
||||
if (retlist == NULL)
|
||||
return FAIL;
|
||||
|
||||
ga_init2(&ga, sizeof(char *), 3);
|
||||
ga_init2(&ga_abbr, sizeof(char *), 3);
|
||||
ga_init2(&ga_kind, sizeof(char *), 3);
|
||||
@@ -4190,7 +4181,7 @@ ExpandUserList(
|
||||
if (li->li_tv.v_type == VAR_STRING)
|
||||
{
|
||||
if (li->li_tv.vval.v_string == NULL)
|
||||
continue; // Skip empty strings
|
||||
continue; // Skip NULL strings
|
||||
p = vim_strsave(li->li_tv.vval.v_string);
|
||||
}
|
||||
else if (li->li_tv.v_type == VAR_DICT
|
||||
@@ -4233,7 +4224,6 @@ ExpandUserList(
|
||||
((char_u **)ga_menu.ga_data)[ga_menu.ga_len++] = menu;
|
||||
((char_u **)ga_info.ga_data)[ga_info.ga_len++] = info;
|
||||
}
|
||||
list_unref(retlist);
|
||||
|
||||
*matches = ga.ga_data;
|
||||
*numMatches = ga.ga_len;
|
||||
@@ -4260,6 +4250,27 @@ ExpandUserList(
|
||||
vim_free(((char_u **)ga_info.ga_data)[i]);
|
||||
vim_free(ga_info.ga_data);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Expand names with a list returned by a function defined by the user.
|
||||
*/
|
||||
static int
|
||||
ExpandUserList(
|
||||
expand_T *xp,
|
||||
char_u ***matches,
|
||||
int *numMatches)
|
||||
{
|
||||
list_T *retlist;
|
||||
|
||||
*matches = NULL;
|
||||
*numMatches = 0;
|
||||
retlist = call_user_expand_func(call_func_retlist, xp);
|
||||
if (retlist == NULL)
|
||||
return FAIL;
|
||||
|
||||
expand_process_user_list(retlist, matches, numMatches, xp);
|
||||
list_unref(retlist);
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
+2
-21
@@ -7066,7 +7066,7 @@ call_findfunc(char_u *pat, int cmdcomplete)
|
||||
* Returns OK on success and FAIL otherwise.
|
||||
*/
|
||||
int
|
||||
expand_findfunc(char_u *pat, char_u ***files, int *numMatches)
|
||||
expand_findfunc(expand_T *xp, char_u *pat, char_u ***files, int *numMatches)
|
||||
{
|
||||
list_T *l;
|
||||
int len;
|
||||
@@ -7086,26 +7086,7 @@ expand_findfunc(char_u *pat, char_u ***files, int *numMatches)
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
*files = ALLOC_MULT(char_u *, len);
|
||||
if (*files == NULL)
|
||||
{
|
||||
list_free(l);
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
// Copy all the List items
|
||||
listitem_T *li;
|
||||
int idx = 0;
|
||||
FOR_ALL_LIST_ITEMS(l, li)
|
||||
{
|
||||
if (li->li_tv.v_type == VAR_STRING)
|
||||
{
|
||||
(*files)[idx] = vim_strsave(li->li_tv.vval.v_string);
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
|
||||
*numMatches = idx;
|
||||
expand_process_user_list(l, files, numMatches, xp);
|
||||
list_free(l);
|
||||
|
||||
return OK;
|
||||
|
||||
@@ -20,6 +20,7 @@ void set_cmd_context(expand_T *xp, char_u *str, int len, int col, int use_ccline
|
||||
int expand_cmdline(expand_T *xp, char_u *str, int col, int *matchcount, char_u ***matches);
|
||||
int ExpandGeneric(char_u *pat, expand_T *xp, regmatch_T *regmatch, char_u ***matches, int *numMatches, char_u *(*func)(expand_T *, int), int escaped);
|
||||
int ExpandGenericExt(char_u *pat, expand_T *xp, regmatch_T *regmatch, char_u ***matches, int *numMatches, char_u *(*func)(expand_T *, int), int escaped, int sortStartIdx);
|
||||
void expand_process_user_list(list_T *retlist, char_u ***matches, int *numMatches, expand_T *xp);
|
||||
void globpath(char_u *path, char_u *file, garray_T *ga, int expand_options, int dirs);
|
||||
int wildmenu_translate_key(cmdline_info_T *cclp, int key, expand_T *xp, int did_wild_list);
|
||||
int wildmenu_process_key(cmdline_info_T *cclp, int key, expand_T *xp);
|
||||
|
||||
@@ -47,7 +47,7 @@ void tabpage_close_other(tabpage_T *tp, int forceit);
|
||||
void ex_stop(exarg_T *eap);
|
||||
void handle_drop(int filec, char_u **filev, int split, void (*callback)(void *), void *cookie);
|
||||
void handle_any_postponed_drop(void);
|
||||
int expand_findfunc(char_u *pat, char_u ***files, int *numMatches);
|
||||
int expand_findfunc(expand_T *xp, char_u *pat, char_u ***files, int *numMatches);
|
||||
char *did_set_findfunc(optset_T *args);
|
||||
void free_findfunc_option(void);
|
||||
int set_ref_in_findfunc(int copyID);
|
||||
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
| +0&#ffffff0@74
|
||||
|~+0#4040ff13&| @73
|
||||
|~| @73
|
||||
|~| @73
|
||||
|~| @73
|
||||
|~| @73
|
||||
|~| @3| +0#0000001#e0e0e08|X|p|l|a|i|n| @8| +0#4040ff13#ffffff0@53
|
||||
|~| @3| +0#0000001#ffd7ff255|X|f|i|l|e|1| |F| |f|i|l|e| @1| +0#4040ff13#ffffff0@53
|
||||
|~| @3| +0#0000001#ffd7ff255|X|f|i|l|e|2| |F| |f|i|l|e| @1| +0#4040ff13#ffffff0@53
|
||||
|~| @3| +0#0000001#ffd7ff255|X|d|i|r|1| @1|D| |d|i|r| @2| +0#4040ff13#ffffff0@53
|
||||
|~| @3| +0#0000001#ffd7ff255|X|d|i|r|2| @1|D| |d|i|r| @2| +0#4040ff13#ffffff0@53
|
||||
|:+0#0000000&|f|i|n|d| |X|p|l|a|i|n> @62
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
| +0&#ffffff0@74
|
||||
|~+0#4040ff13&| @73
|
||||
|~| @73
|
||||
|~| @73
|
||||
|~| @73
|
||||
|~| @73
|
||||
|~| @3| +0#0000001#ffd7ff255|X|p|l|a|i|n| @8| +0#4040ff13#ffffff0@53
|
||||
|~| @3| +0#0000001#ffd7ff255|X|f|i|l|e|1| |F| |f|i|l|e| @1| +0#4040ff13#ffffff0@53
|
||||
|~| @3| +0#0000001#ffd7ff255|X|f|i|l|e|2| |F| |f|i|l|e| @1|╔+0&#e0e0e08|═@8|X| +0#4040ff13#ffffff0@42
|
||||
|~| @3| +0#0000001#e0e0e08|X|d|i|r|1| @1|D| |d|i|r| @2|║| |1|s|t| |d|i|r| |║| +0#4040ff13#ffffff0@42
|
||||
|~| @3| +0#0000001#ffd7ff255|X|d|i|r|2| @1|D| |d|i|r| @2|╚+0&#e0e0e08|═@8|⇲| +0#4040ff13#ffffff0@42
|
||||
|:+0#0000000&|f|i|n|d| |X|d|i|r|1> @63
|
||||
@@ -4705,6 +4705,38 @@ func Test_customlist_dict_completion_info_popup()
|
||||
call StopVimInTerminal(buf)
|
||||
endfunc
|
||||
|
||||
func Test_cmdline_complete_findfunc_dict()
|
||||
CheckScreendump
|
||||
|
||||
let lines =<< trim END
|
||||
set wildmenu wildoptions=pum completeopt=menu,popup
|
||||
func FindComplete(cmdarg, cmdcomplete)
|
||||
return [
|
||||
\ 'Xplain',
|
||||
\ {'word': 'Xfile1', 'kind': 'F', 'menu': 'file', 'info': '1st file'},
|
||||
\ {'word': 'Xfile2', 'kind': 'F', 'menu': 'file', 'info': '2nd file'},
|
||||
\ {'word': 'Xdir1', 'kind': 'D', 'menu': 'dir', 'info': '1st dir'},
|
||||
\ {'word': 'Xdir2', 'kind': 'D', 'menu': 'dir', 'info': '2nd dir'},
|
||||
\ ]
|
||||
endfunc
|
||||
set findfunc=FindComplete
|
||||
END
|
||||
call writefile(lines, 'XTest_compl_findfunc_dict', 'D')
|
||||
let rows = 12
|
||||
let buf = RunVimInTerminal('-S XTest_compl_findfunc_dict', {'rows': rows})
|
||||
|
||||
call term_sendkeys(buf, ":find \<Tab>")
|
||||
call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':find Xplain') + 1)], g:test_timeout, ((rows - 5), '^\~\s\+Xplain\s\+$'))
|
||||
call VerifyScreenDump(buf, 'Test_compl_findfunc_dict_01', {})
|
||||
|
||||
call term_sendkeys(buf, "\<PageDown>")
|
||||
call WaitForTermCurPosAndLinesToMatch(buf, [rows, (strlen(':find Xdir1') + 1)], g:test_timeout, ((rows - 2), '1st dir'))
|
||||
call VerifyScreenDump(buf, 'Test_compl_findfunc_dict_02', {})
|
||||
|
||||
call term_sendkeys(buf, "\<Esc>")
|
||||
call StopVimInTerminal(buf)
|
||||
endfunc
|
||||
|
||||
func Test_custom_completion_with_glob()
|
||||
func TestGlobComplete(A, L, P)
|
||||
return split(glob('Xglob*'), "\n")
|
||||
|
||||
@@ -729,6 +729,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
451,
|
||||
/**/
|
||||
450,
|
||||
/**/
|
||||
|
||||
Reference in New Issue
Block a user