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
• |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.
==============================================================================

View File

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

View File

@ -3342,18 +3342,17 @@ getcmdcomplpat() *getcmdcomplpat()*
Return: ~
(`string`)
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_=|.
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_=|.
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?`)
To get the type of the command-line completion for the
specified string, use |getcompletiontype()|.
Return: ~
(`string`)
@ -3514,6 +3513,19 @@ getcompletion({pat}, {type} [, {filtered}]) *getcompletion()*
Return: ~
(`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()*
Get the position of the cursor. This is like getpos('.'), but
includes an extra "curswant" item in the list:

View File

@ -2994,18 +2994,19 @@ function vim.fn.getcharstr(expr, opts) end
--- @return string
function vim.fn.getcmdcomplpat() end
--- 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_=|.
---
--- 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_=|.
--- 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
--- To get the type of the command-line completion for the
--- specified string, use |getcompletiontype()|.
---
--- @return string
function vim.fn.getcmdcompltype(pat) end
function vim.fn.getcmdcompltype() end
--- Return the current command-line input. Only works when the
--- command line is being edited, thus requires use of
@ -3154,6 +3155,16 @@ function vim.fn.getcmdwintype() end
--- @return string[]
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
--- includes an extra "curswant" item in the list:
--- [0, lnum, col, off, curswant] ~

View File

@ -3838,6 +3838,30 @@ theend:
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
void f_cmdcomplete_info(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
{

View File

@ -3751,22 +3751,22 @@ M.funcs = {
signature = 'getcmdcomplpat()',
},
getcmdcompltype = {
args = { 0, 1 },
base = 1,
desc = [=[
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_=|.
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_=|.
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.
To get the type of the command-line completion for the
specified string, use |getcompletiontype()|.
]=],
name = 'getcmdcompltype',
params = { { 'pat', 'string' } },
params = {},
returns = 'string',
signature = 'getcmdcompltype([{pat}])',
signature = 'getcmdcompltype()',
},
getcmdline = {
desc = [=[
@ -3943,6 +3943,21 @@ M.funcs = {
returns = 'string[]',
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 = {
args = { 0, 1 },
base = 1,

View File

@ -4197,8 +4197,8 @@ static char *get_cmdline_completion_pattern(void)
return xstrdup(compl_pat);
}
/// Get the current command-line completion type.
static char *get_cmdline_completion(expand_T *xpc)
/// Get the command-line completion type.
char *get_cmdline_completion(expand_T *xpc)
{
int xp_context = xpc->xp_context;
if (xp_context == EXPAND_NOTHING) {
@ -4235,27 +4235,9 @@ 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 = NULL;
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;
@ -4263,7 +4245,6 @@ void f_getcmdcompltype(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
rettv->vval.v_string = get_cmdline_completion(p->xpc);
}
}
/// "getcmdline()" function
void f_getcmdline(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)

View File

@ -737,6 +737,31 @@ func Test_getcompletion()
call assert_fails('call getcompletion("abc", [])', 'E1174:')
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'
func Test_getcompletion_wildoptions()
let save_wildoptions = &wildoptions
@ -4601,14 +4626,4 @@ 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