vim-patch:9.1.1505: not possible to return completion type for :ex command

Problem:  not possible to return command-line completion type for :ex
          command
Solution: make getcmdcompltype() accept an optional and return the
          command-line completion for that arg (Shougo Matsushita).

closes: vim/vim#17606

5d2354fc07

Co-authored-by: Shougo Matsushita <Shougo.Matsu@gmail.com>
This commit is contained in:
zeertzjq
2025-07-06 08:29:46 +08:00
parent 8fe4e120a2
commit 6ebcb4a4d6
6 changed files with 67 additions and 32 deletions

View File

@ -908,8 +908,7 @@ Buffers, windows and the argument list:
Command line: *command-line-functions*
getcmdcomplpat() get completion pattern of the current command
line
getcmdcompltype() get the type of the current command line
completion
getcmdcompltype() get the type of the command line completion
getcmdline() get the current command line input
getcmdprompt() get the current command line prompt
getcmdpos() get position of the cursor in the command line

View File

@ -3342,15 +3342,19 @@ getcmdcomplpat() *getcmdcomplpat()*
Return: ~
(`string`)
getcmdcompltype() *getcmdcompltype()*
Return the type of the current command-line completion.
Only works when the command line is being edited, thus
requires use of |c_CTRL-\_e| or |c_CTRL-R_=|.
getcmdcompltype([{pat}]) *getcmdcompltype()*
Return the type of command-line completion using {pat}.
If {pat} is omited, only works when the command line is being
edited, thus requires use of |c_CTRL-\_e| or |c_CTRL-R_=|.
See |:command-completion| for the return string.
Also see |getcmdtype()|, |setcmdpos()|, |getcmdline()|,
|getcmdprompt()|, |getcmdcomplpat()| and |setcmdline()|.
Returns an empty string when completion is not defined.
Parameters: ~
• {pat} (`string?`)
Return: ~
(`string`)

View File

@ -2994,16 +2994,18 @@ function vim.fn.getcharstr(expr, opts) end
--- @return string
function vim.fn.getcmdcomplpat() end
--- Return the type of the current command-line completion.
--- Only works when the command line is being edited, thus
--- requires use of |c_CTRL-\_e| or |c_CTRL-R_=|.
--- Return the type of command-line completion using {pat}.
--- If {pat} is omited, only works when the command line is being
--- edited, thus requires use of |c_CTRL-\_e| or |c_CTRL-R_=|.
---
--- See |:command-completion| for the return string.
--- Also see |getcmdtype()|, |setcmdpos()|, |getcmdline()|,
--- |getcmdprompt()|, |getcmdcomplpat()| and |setcmdline()|.
--- Returns an empty string when completion is not defined.
---
--- @param pat? string
--- @return string
function vim.fn.getcmdcompltype() end
function vim.fn.getcmdcompltype(pat) end
--- Return the current command-line input. Only works when the
--- command line is being edited, thus requires use of

View File

@ -3751,19 +3751,22 @@ M.funcs = {
signature = 'getcmdcomplpat()',
},
getcmdcompltype = {
args = { 0, 1 },
base = 1,
desc = [=[
Return the type of the current command-line completion.
Only works when the command line is being edited, thus
requires use of |c_CTRL-\_e| or |c_CTRL-R_=|.
Return the type of command-line completion using {pat}.
If {pat} is omited, only works when the command line is being
edited, thus requires use of |c_CTRL-\_e| or |c_CTRL-R_=|.
See |:command-completion| for the return string.
Also see |getcmdtype()|, |setcmdpos()|, |getcmdline()|,
|getcmdprompt()|, |getcmdcomplpat()| and |setcmdline()|.
Returns an empty string when completion is not defined.
]=],
name = 'getcmdcompltype',
params = {},
params = { { 'pat', 'string' } },
returns = 'string',
signature = 'getcmdcompltype()',
signature = 'getcmdcompltype([{pat}])',
},
getcmdline = {
desc = [=[

View File

@ -4198,22 +4198,13 @@ static char *get_cmdline_completion_pattern(void)
}
/// Get the current command-line completion type.
static char *get_cmdline_completion(void)
static char *get_cmdline_completion(expand_T *xpc)
{
if (cmdline_star > 0) {
return NULL;
}
CmdlineInfo *p = get_ccline_ptr();
if (p == NULL || p->xpc == NULL) {
return NULL;
}
int xp_context = p->xpc->xp_context;
int xp_context = xpc->xp_context;
if (xp_context == EXPAND_NOTHING) {
set_expand_context(p->xpc);
xp_context = p->xpc->xp_context;
p->xpc->xp_context = EXPAND_NOTHING;
set_expand_context(xpc);
xp_context = xpc->xp_context;
xpc->xp_context = EXPAND_NOTHING;
}
if (xp_context == EXPAND_UNSUCCESSFUL) {
return NULL;
@ -4225,9 +4216,9 @@ static char *get_cmdline_completion(void)
}
if (xp_context == EXPAND_USER_LIST || xp_context == EXPAND_USER_DEFINED) {
size_t buflen = strlen(cmd_compl) + strlen(p->xpc->xp_arg) + 2;
size_t buflen = strlen(cmd_compl) + strlen(xpc->xp_arg) + 2;
char *buffer = xmalloc(buflen);
snprintf(buffer, buflen, "%s,%s", cmd_compl, p->xpc->xp_arg);
snprintf(buffer, buflen, "%s,%s", cmd_compl, xpc->xp_arg);
return buffer;
}
@ -4244,8 +4235,34 @@ void f_getcmdcomplpat(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
/// "getcmdcompltype()" function
void f_getcmdcompltype(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
{
if (tv_check_for_opt_string_arg(argvars, 0) == FAIL) {
return;
}
rettv->v_type = VAR_STRING;
rettv->vval.v_string = get_cmdline_completion();
if (argvars[0].v_type != VAR_UNKNOWN) {
char *pat = (char *)tv_get_string(&argvars[0]);
expand_T xpc;
ExpandInit(&xpc);
int cmdline_len = (int)strlen(pat);
set_cmd_context(&xpc, pat, cmdline_len, cmdline_len, false);
xpc.xp_pattern_len = strlen(xpc.xp_pattern);
xpc.xp_col = cmdline_len;
rettv->v_type = VAR_STRING;
rettv->vval.v_string = get_cmdline_completion(&xpc);
ExpandCleanup(&xpc);
} else {
CmdlineInfo *p = get_ccline_ptr();
if (cmdline_star > 0 || p == NULL || p->xpc == NULL) {
return;
}
rettv->vval.v_string = get_cmdline_completion(p->xpc);
}
}
/// "getcmdline()" function

View File

@ -4601,4 +4601,14 @@ func Test_range_complete()
set wildcharm=0
endfunc
func Test_getcmdcompltype_with_pat()
call assert_fails('call getcmdcompltype({})', 'E1174:')
call assert_equal(getcmdcompltype(''), 'command')
call assert_equal(getcmdcompltype('dummy '), '')
call assert_equal(getcmdcompltype('cd '), 'dir_in_path')
call assert_equal(getcmdcompltype('let v:n'), 'var')
call assert_equal(getcmdcompltype('call tag'), 'function')
call assert_equal(getcmdcompltype('help '), 'help')
endfunc
" vim: shiftwidth=2 sts=2 expandtab