vim-patch:9.1.1509: patch 9.1.1505 was not good

Problem:  Patch 9.1.1505 was not good
Solution: Revert "patch 9.1.1505: not possible to return completion type
          for :ex command" and instead add the getcompletiontype()
          function (Hirohito Higashi).

related: vim/vim#17606
closes: vim/vim#17662

96b3ef2389

Cherry-pick Test_multibyte_expression() from Vim, as it passes.

Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
Co-authored-by: Shougo Matsushita <Shougo.Matsu@gmail.com>
This commit is contained in:
zeertzjq
2025-07-06 08:41:41 +08:00
parent 6ebcb4a4d6
commit 9c04eb02ad
8 changed files with 121 additions and 59 deletions

View File

@ -269,6 +269,7 @@ UI
VIMSCRIPT VIMSCRIPT
• |cmdcomplete_info()| gets current cmdline completion info. • |cmdcomplete_info()| gets current cmdline completion info.
• |getcompletiontype()| gets command-line completion type for any string.
• |prompt_getinput()| gets current user-input in prompt-buffer. • |prompt_getinput()| gets current user-input in prompt-buffer.
============================================================================== ==============================================================================

View File

@ -908,7 +908,8 @@ 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 command line completion getcmdcompltype() get the type of the current command line
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
@ -919,6 +920,8 @@ Command line: *command-line-functions*
getcmdtype() return the current command-line type getcmdtype() return the current command-line type
getcmdwintype() return the current command-line window type getcmdwintype() return the current command-line window type
getcompletion() list of command-line completion matches getcompletion() list of command-line completion matches
getcompletiontype() get the type of the command-line completion
for specified string
fullcommand() get full command name fullcommand() get full command name
cmdcomplete_info() get command-line completion information cmdcomplete_info() get command-line completion information

View File

@ -3342,18 +3342,17 @@ getcmdcomplpat() *getcmdcomplpat()*
Return: ~ Return: ~
(`string`) (`string`)
getcmdcompltype([{pat}]) *getcmdcompltype()* getcmdcompltype() *getcmdcompltype()*
Return the type of command-line completion using {pat}. Return the type of the current command-line completion.
If {pat} is omited, only works when the command line is being Only works when the command line is being edited, thus
edited, thus requires use of |c_CTRL-\_e| or |c_CTRL-R_=|. 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: ~ To get the type of the command-line completion for the
• {pat} (`string?`) specified string, use |getcompletiontype()|.
Return: ~ Return: ~
(`string`) (`string`)
@ -3514,6 +3513,19 @@ getcompletion({pat}, {type} [, {filtered}]) *getcompletion()*
Return: ~ Return: ~
(`string[]`) (`string[]`)
getcompletiontype({pat}) *getcompletiontype()*
Return the type of the command-line completion using {pat}.
When no corresponding completion type is found, an empty
string is returned.
To get the current command-line completion type, use
|getcmdcompltype()|.
Parameters: ~
• {pat} (`string`)
Return: ~
(`string`)
getcurpos([{winid}]) *getcurpos()* getcurpos([{winid}]) *getcurpos()*
Get the position of the cursor. This is like getpos('.'), but Get the position of the cursor. This is like getpos('.'), but
includes an extra "curswant" item in the list: includes an extra "curswant" item in the list:

View File

@ -2994,18 +2994,19 @@ 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 command-line completion using {pat}. --- Return the type of the current command-line completion.
--- If {pat} is omited, only works when the command line is being --- Only works when the command line is being edited, thus
--- edited, thus requires use of |c_CTRL-\_e| or |c_CTRL-R_=|. --- 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 --- To get the type of the command-line completion for the
--- specified string, use |getcompletiontype()|.
---
--- @return string --- @return string
function vim.fn.getcmdcompltype(pat) end function vim.fn.getcmdcompltype() 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
@ -3154,6 +3155,16 @@ function vim.fn.getcmdwintype() end
--- @return string[] --- @return string[]
function vim.fn.getcompletion(pat, type, filtered) end function vim.fn.getcompletion(pat, type, filtered) end
--- Return the type of the command-line completion using {pat}.
--- When no corresponding completion type is found, an empty
--- string is returned.
--- To get the current command-line completion type, use
--- |getcmdcompltype()|.
---
--- @param pat string
--- @return string
function vim.fn.getcompletiontype(pat) end
--- Get the position of the cursor. This is like getpos('.'), but --- Get the position of the cursor. This is like getpos('.'), but
--- includes an extra "curswant" item in the list: --- includes an extra "curswant" item in the list:
--- [0, lnum, col, off, curswant] ~ --- [0, lnum, col, off, curswant] ~

View File

@ -3838,6 +3838,30 @@ theend:
ExpandCleanup(&xpc); ExpandCleanup(&xpc);
} }
/// "getcompletiontype()" function
void f_getcompletiontype(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
{
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
if (tv_check_for_string_arg(argvars, 0) == FAIL) {
return;
}
const char *pat = tv_get_string(&argvars[0]);
expand_T xpc;
ExpandInit(&xpc);
int cmdline_len = (int)strlen(pat);
set_cmd_context(&xpc, (char *)pat, cmdline_len, cmdline_len, false);
xpc.xp_pattern_len = strlen(xpc.xp_pattern);
xpc.xp_col = cmdline_len;
rettv->vval.v_string = get_cmdline_completion(&xpc);
ExpandCleanup(&xpc);
}
/// "cmdcomplete_info()" function /// "cmdcomplete_info()" function
void f_cmdcomplete_info(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) void f_cmdcomplete_info(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
{ {

View File

@ -3751,22 +3751,22 @@ M.funcs = {
signature = 'getcmdcomplpat()', signature = 'getcmdcomplpat()',
}, },
getcmdcompltype = { getcmdcompltype = {
args = { 0, 1 },
base = 1,
desc = [=[ desc = [=[
Return the type of command-line completion using {pat}. Return the type of the current command-line completion.
If {pat} is omited, only works when the command line is being Only works when the command line is being edited, thus
edited, thus requires use of |c_CTRL-\_e| or |c_CTRL-R_=|. 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.
To get the type of the command-line completion for the
specified string, use |getcompletiontype()|.
]=], ]=],
name = 'getcmdcompltype', name = 'getcmdcompltype',
params = { { 'pat', 'string' } }, params = {},
returns = 'string', returns = 'string',
signature = 'getcmdcompltype([{pat}])', signature = 'getcmdcompltype()',
}, },
getcmdline = { getcmdline = {
desc = [=[ desc = [=[
@ -3943,6 +3943,21 @@ M.funcs = {
returns = 'string[]', returns = 'string[]',
signature = 'getcompletion({pat}, {type} [, {filtered}])', signature = 'getcompletion({pat}, {type} [, {filtered}])',
}, },
getcompletiontype = {
args = 1,
base = 1,
desc = [=[
Return the type of the command-line completion using {pat}.
When no corresponding completion type is found, an empty
string is returned.
To get the current command-line completion type, use
|getcmdcompltype()|.
]=],
name = 'getcompletiontype',
params = { { 'pat', 'string' } },
returns = 'string',
signature = 'getcompletiontype({pat})',
},
getcurpos = { getcurpos = {
args = { 0, 1 }, args = { 0, 1 },
base = 1, base = 1,

View File

@ -4197,8 +4197,8 @@ static char *get_cmdline_completion_pattern(void)
return xstrdup(compl_pat); return xstrdup(compl_pat);
} }
/// Get the current command-line completion type. /// Get the command-line completion type.
static char *get_cmdline_completion(expand_T *xpc) char *get_cmdline_completion(expand_T *xpc)
{ {
int xp_context = xpc->xp_context; int xp_context = xpc->xp_context;
if (xp_context == EXPAND_NOTHING) { if (xp_context == EXPAND_NOTHING) {
@ -4235,34 +4235,15 @@ 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) { rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
CmdlineInfo *p = get_ccline_ptr();
if (cmdline_star > 0 || p == NULL || p->xpc == NULL) {
return; return;
} }
rettv->v_type = VAR_STRING; rettv->vval.v_string = get_cmdline_completion(p->xpc);
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

@ -737,6 +737,31 @@ func Test_getcompletion()
call assert_fails('call getcompletion("abc", [])', 'E1174:') call assert_fails('call getcompletion("abc", [])', 'E1174:')
endfunc endfunc
func Test_getcompletiontype()
call assert_fails('call getcompletiontype()', 'E119:')
call assert_fails('call getcompletiontype({})', 'E1174:')
call assert_equal(getcompletiontype(''), 'command')
call assert_equal(getcompletiontype('dummy '), '')
call assert_equal(getcompletiontype('cd '), 'dir_in_path')
call assert_equal(getcompletiontype('let v:n'), 'var')
call assert_equal(getcompletiontype('call tag'), 'function')
call assert_equal(getcompletiontype('help '), 'help')
endfunc
func Test_multibyte_expression()
" Get a dialog in the GUI
CheckNotGui
" This was using uninitialized memory.
let lines =<< trim END
set verbose=6
norm @=ٷ
qall!
END
call writefile(lines, 'XmultiScript', 'D')
call RunVim('', '', '-u NONE -n -e -s -S XmultiScript')
endfunc
" Test for getcompletion() with "fuzzy" in 'wildoptions' " Test for getcompletion() with "fuzzy" in 'wildoptions'
func Test_getcompletion_wildoptions() func Test_getcompletion_wildoptions()
let save_wildoptions = &wildoptions let save_wildoptions = &wildoptions
@ -4601,14 +4626,4 @@ 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