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* Command line: *command-line-functions*
getcmdcomplpat() get completion pattern of the current command getcmdcomplpat() get completion pattern of the current command
line line
getcmdcompltype() get the type of the current command line getcmdcompltype() get the type of the command line completion
completion
getcmdline() get the current command line input getcmdline() get the current command line input
getcmdprompt() get the current command line prompt getcmdprompt() get the current command line prompt
getcmdpos() get position of the cursor in the command line getcmdpos() get position of the cursor in the command line

View File

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

View File

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

View File

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

View File

@@ -4198,22 +4198,13 @@ static char *get_cmdline_completion_pattern(void)
} }
/// Get the current command-line completion type. /// 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) { int xp_context = xpc->xp_context;
return NULL;
}
CmdlineInfo *p = get_ccline_ptr();
if (p == NULL || p->xpc == NULL) {
return NULL;
}
int xp_context = p->xpc->xp_context;
if (xp_context == EXPAND_NOTHING) { if (xp_context == EXPAND_NOTHING) {
set_expand_context(p->xpc); set_expand_context(xpc);
xp_context = p->xpc->xp_context; xp_context = xpc->xp_context;
p->xpc->xp_context = EXPAND_NOTHING; xpc->xp_context = EXPAND_NOTHING;
} }
if (xp_context == EXPAND_UNSUCCESSFUL) { if (xp_context == EXPAND_UNSUCCESSFUL) {
return NULL; return NULL;
@@ -4225,9 +4216,9 @@ static char *get_cmdline_completion(void)
} }
if (xp_context == EXPAND_USER_LIST || xp_context == EXPAND_USER_DEFINED) { 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); 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; return buffer;
} }
@@ -4244,8 +4235,34 @@ void f_getcmdcomplpat(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
/// "getcmdcompltype()" function /// "getcmdcompltype()" function
void f_getcmdcompltype(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) 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->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 /// "getcmdline()" function

View File

@@ -4601,4 +4601,14 @@ func Test_range_complete()
set wildcharm=0 set wildcharm=0
endfunc 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 " vim: shiftwidth=2 sts=2 expandtab