diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index df62f5a5d3..76cc711c63 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -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. ============================================================================== diff --git a/runtime/doc/usr_41.txt b/runtime/doc/usr_41.txt index 6bce7e0ab3..45d996effb 100644 --- a/runtime/doc/usr_41.txt +++ b/runtime/doc/usr_41.txt @@ -920,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 diff --git a/runtime/doc/vimfn.txt b/runtime/doc/vimfn.txt index 172eb72675..e549042687 100644 --- a/runtime/doc/vimfn.txt +++ b/runtime/doc/vimfn.txt @@ -3351,6 +3351,9 @@ getcmdcompltype() *getcmdcompltype()* |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()|. + Return: ~ (`string`) @@ -3510,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: diff --git a/runtime/lua/vim/_meta/vimfn.lua b/runtime/lua/vim/_meta/vimfn.lua index 4443e8c729..d690eaa34a 100644 --- a/runtime/lua/vim/_meta/vimfn.lua +++ b/runtime/lua/vim/_meta/vimfn.lua @@ -3002,6 +3002,9 @@ function vim.fn.getcmdcomplpat() end --- |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()|. +--- --- @return string function vim.fn.getcmdcompltype() end @@ -3152,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] ~ diff --git a/src/nvim/cmdexpand.c b/src/nvim/cmdexpand.c index a1d7ae7e2c..4132e56142 100644 --- a/src/nvim/cmdexpand.c +++ b/src/nvim/cmdexpand.c @@ -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) { diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index 61e76707bc..80f73ac209 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -3759,6 +3759,9 @@ M.funcs = { 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 = {}, @@ -3940,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, diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index c67253e142..8ad5739bb3 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -4197,23 +4197,14 @@ static char *get_cmdline_completion_pattern(void) return xstrdup(compl_pat); } -/// Get the current command-line completion type. -static char *get_cmdline_completion(void) +/// Get the command-line completion type. +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; } @@ -4245,7 +4236,14 @@ void f_getcmdcomplpat(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) void f_getcmdcompltype(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { rettv->v_type = VAR_STRING; - rettv->vval.v_string = get_cmdline_completion(); + rettv->vval.v_string = NULL; + + 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 diff --git a/test/old/testdir/test_cmdline.vim b/test/old/testdir/test_cmdline.vim index 454390dd6b..9b13bc948e 100644 --- a/test/old/testdir/test_cmdline.vim +++ b/test/old/testdir/test_cmdline.vim @@ -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