vim-patch:9.0.1774: no support for custom cmdline completion (#24808)

Problem:  no support for custom cmdline completion
Solution: Add new vimscript functions

Add the following two functions:
- getcmdcompltype() returns custom and customlist functions

- getcompletion() supports both custom and customlist

closes: vim/vim#12228

92997dda78

Co-authored-by: Shougo Matsushita <Shougo.Matsu@gmail.com>
This commit is contained in:
zeertzjq 2023-08-21 07:29:49 +08:00 committed by GitHub
parent ac99e63d73
commit 694814cdd5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 87 additions and 6 deletions

View File

@ -2354,6 +2354,8 @@ getcompletion({pat}, {type} [, {filtered}]) *getcompletion()*
color color schemes color color schemes
command Ex command command Ex command
compiler compilers compiler compilers
custom,{func} custom completion, defined via {func}
customlist,{func} custom completion, defined via {func}
diff_buffer |:diffget| and |:diffput| completion diff_buffer |:diffget| and |:diffput| completion
dir directory names dir directory names
environment environment variable names environment environment variable names

View File

@ -2871,6 +2871,8 @@ function vim.fn.getcmdwintype() end
--- color color schemes --- color color schemes
--- command Ex command --- command Ex command
--- compiler compilers --- compiler compilers
--- custom,{func} custom completion, defined via {func}
--- customlist,{func} custom completion, defined via {func}
--- diff_buffer |:diffget| and |:diffput| completion --- diff_buffer |:diffget| and |:diffput| completion
--- dir directory names --- dir directory names
--- environment environment variable names --- environment environment variable names

View File

@ -3515,12 +3515,34 @@ void f_getcompletion(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
ExpandInit(&xpc); ExpandInit(&xpc);
xpc.xp_pattern = (char *)pattern; xpc.xp_pattern = (char *)pattern;
xpc.xp_pattern_len = strlen(xpc.xp_pattern); xpc.xp_pattern_len = strlen(xpc.xp_pattern);
xpc.xp_line = (char *)pattern;
xpc.xp_context = cmdcomplete_str_to_type(type); xpc.xp_context = cmdcomplete_str_to_type(type);
if (xpc.xp_context == EXPAND_NOTHING) { if (xpc.xp_context == EXPAND_NOTHING) {
semsg(_(e_invarg2), type); semsg(_(e_invarg2), type);
return; return;
} }
if (xpc.xp_context == EXPAND_USER_DEFINED) {
// Must be "custom,funcname" pattern
if (strncmp(type, "custom,", 7) != 0) {
semsg(_(e_invarg2), type);
return;
}
xpc.xp_arg = (char *)(type + 7);
}
if (xpc.xp_context == EXPAND_USER_LIST) {
// Must be "customlist,funcname" pattern
if (strncmp(type, "customlist,", 11) != 0) {
semsg(_(e_invarg2), type);
return;
}
xpc.xp_arg = (char *)(type + 11);
}
if (xpc.xp_context == EXPAND_MENUS) { if (xpc.xp_context == EXPAND_MENUS) {
set_context_in_menu_cmd(&xpc, "menu", xpc.xp_pattern, false); set_context_in_menu_cmd(&xpc, "menu", xpc.xp_pattern, false);
xpc.xp_pattern_len = strlen(xpc.xp_pattern); xpc.xp_pattern_len = strlen(xpc.xp_pattern);

View File

@ -3582,6 +3582,8 @@ M.funcs = {
color color schemes color color schemes
command Ex command command Ex command
compiler compilers compiler compilers
custom,{func} custom completion, defined via {func}
customlist,{func} custom completion, defined via {func}
diff_buffer |:diffget| and |:diffput| completion diff_buffer |:diffget| and |:diffput| completion
dir directory names dir directory names
environment environment variable names environment environment variable names

View File

@ -4165,11 +4165,19 @@ static char *get_cmdline_completion(void)
} }
char *cmd_compl = get_user_cmd_complete(p->xpc, p->xpc->xp_context); char *cmd_compl = get_user_cmd_complete(p->xpc, p->xpc->xp_context);
if (cmd_compl != NULL) { if (cmd_compl == NULL) {
return xstrdup(cmd_compl); return NULL;
} }
return NULL; if (p->xpc->xp_context == EXPAND_USER_LIST
|| p->xpc->xp_context == EXPAND_USER_DEFINED) {
size_t buflen = strlen(cmd_compl) + strlen(p->xpc->xp_arg) + 2;
char *buffer = xmalloc(buflen);
snprintf(buffer, buflen, "%s,%s", cmd_compl, p->xpc->xp_arg);
return buffer;
}
return xstrdup(cmd_compl);
} }
/// "getcmdcompltype()" function /// "getcmdcompltype()" function

View File

@ -425,6 +425,13 @@ char *get_user_cmd_complete(expand_T *xp, int idx)
int cmdcomplete_str_to_type(const char *complete_str) int cmdcomplete_str_to_type(const char *complete_str)
{ {
if (strncmp(complete_str, "custom,", 7) == 0) {
return EXPAND_USER_DEFINED;
}
if (strncmp(complete_str, "customlist,", 11) == 0) {
return EXPAND_USER_LIST;
}
for (int i = 0; i < (int)(ARRAY_SIZE(command_complete)); i++) { for (int i = 0; i < (int)(ARRAY_SIZE(command_complete)); i++) {
char *cmd_compl = get_command_complete(i); char *cmd_compl = get_command_complete(i);
if (cmd_compl == NULL) { if (cmd_compl == NULL) {

View File

@ -3649,4 +3649,42 @@ func Test_getcompletion_usercmd()
delcom TestCompletion delcom TestCompletion
endfunc endfunc
func Test_custom_completion()
func CustomComplete1(lead, line, pos)
return "a\nb\nc"
endfunc
func CustomComplete2(lead, line, pos)
return ['a', 'b']->filter({ _, val -> val->stridx(a:lead) == 0 })
endfunc
func Check_custom_completion()
call assert_equal('custom,CustomComplete1', getcmdcompltype())
return ''
endfunc
func Check_customlist_completion()
call assert_equal('customlist,CustomComplete2', getcmdcompltype())
return ''
endfunc
command -nargs=1 -complete=custom,CustomComplete1 Test1 echo
command -nargs=1 -complete=customlist,CustomComplete2 Test2 echo
call feedkeys(":Test1 \<C-R>=Check_custom_completion()\<CR>\<Esc>", "xt")
call feedkeys(":Test2 \<C-R>=Check_customlist_completion()\<CR>\<Esc>", "xt")
call assert_fails("call getcompletion('', 'custom')", 'E475:')
call assert_fails("call getcompletion('', 'customlist')", 'E475:')
call assert_equal(getcompletion('', 'custom,CustomComplete1'), ['a', 'b', 'c'])
call assert_equal(getcompletion('', 'customlist,CustomComplete2'), ['a', 'b'])
call assert_equal(getcompletion('b', 'customlist,CustomComplete2'), ['b'])
delcom Test1
delcom Test2
delfunc CustomComplete1
delfunc CustomComplete2
delfunc Check_custom_completion
delfunc Check_customlist_completion
endfunc
" vim: shiftwidth=2 sts=2 expandtab " vim: shiftwidth=2 sts=2 expandtab