patch 8.2.0925: getcompletion() does not return command line arguments
Problem: Getcompletion() does not return command line arguments.
Solution: Add the "cmdline" option. (Shougo, closes #1140)
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 52994f1..94fc497 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -5112,6 +5112,7 @@
behave :behave suboptions
color color schemes
command Ex command (and arguments)
+ cmdline |cmdline-completion| result
compiler compilers
cscope |:cscope| suboptions
diff_buffer |:diffget| and |:diffput| completion
@@ -5142,14 +5143,19 @@
user user names
var user variables
- If {pat} is an empty string, then all the matches are returned.
- Otherwise only items matching {pat} are returned. See
- |wildcards| for the use of special characters in {pat}.
+ If {pat} is an empty string, then all the matches are
+ returned. Otherwise only items matching {pat} are returned.
+ See |wildcards| for the use of special characters in {pat}.
If the optional {filtered} flag is set to 1, then 'wildignore'
is applied to filter the results. Otherwise all the matches
are returned. The 'wildignorecase' option always applies.
+ If {type} is "cmdline", then the |cmdline-completion| result is
+ returned. For example, to complete the possible values after
+ a ":call" command: >
+ echo getcompletion('call ', 'cmdline')
+<
If there are no matches, an empty list is returned. An
invalid value for {type} produces an error.
diff --git a/src/cmdexpand.c b/src/cmdexpand.c
index 3a2b10c..f84bf7a 100644
--- a/src/cmdexpand.c
+++ b/src/cmdexpand.c
@@ -2675,10 +2675,18 @@
f_getcompletion(typval_T *argvars, typval_T *rettv)
{
char_u *pat;
+ char_u *type;
expand_T xpc;
int filtered = FALSE;
int options = WILD_SILENT | WILD_USE_NL | WILD_ADD_SLASH
- | WILD_NO_BEEP;
+ | WILD_NO_BEEP;
+
+ if (argvars[1].v_type != VAR_STRING)
+ {
+ semsg(_(e_invarg2), "type must be a string");
+ return;
+ }
+ type = tv_get_string(&argvars[1]);
if (argvars[2].v_type != VAR_UNKNOWN)
filtered = tv_get_number_chk(&argvars[2], NULL);
@@ -2691,39 +2699,45 @@
options |= WILD_KEEP_ALL;
ExpandInit(&xpc);
- xpc.xp_pattern = tv_get_string(&argvars[0]);
- xpc.xp_pattern_len = (int)STRLEN(xpc.xp_pattern);
- xpc.xp_context = cmdcomplete_str_to_type(tv_get_string(&argvars[1]));
- if (xpc.xp_context == EXPAND_NOTHING)
+ if (STRCMP(type, "cmdline") == 0)
{
- if (argvars[1].v_type == VAR_STRING)
- semsg(_(e_invarg2), argvars[1].vval.v_string);
- else
- emsg(_(e_invarg));
- return;
+ set_one_cmd_context(&xpc, tv_get_string(&argvars[0]));
+ xpc.xp_pattern_len = (int)STRLEN(xpc.xp_pattern);
}
+ else
+ {
+ xpc.xp_pattern = tv_get_string(&argvars[0]);
+ xpc.xp_pattern_len = (int)STRLEN(xpc.xp_pattern);
+
+ xpc.xp_context = cmdcomplete_str_to_type(type);
+ if (xpc.xp_context == EXPAND_NOTHING)
+ {
+ semsg(_(e_invarg2), type);
+ return;
+ }
# if defined(FEAT_MENU)
- if (xpc.xp_context == EXPAND_MENUS)
- {
- set_context_in_menu_cmd(&xpc, (char_u *)"menu", xpc.xp_pattern, FALSE);
- xpc.xp_pattern_len = (int)STRLEN(xpc.xp_pattern);
- }
+ if (xpc.xp_context == EXPAND_MENUS)
+ {
+ set_context_in_menu_cmd(&xpc, (char_u *)"menu", xpc.xp_pattern, FALSE);
+ xpc.xp_pattern_len = (int)STRLEN(xpc.xp_pattern);
+ }
# endif
# ifdef FEAT_CSCOPE
- if (xpc.xp_context == EXPAND_CSCOPE)
- {
- set_context_in_cscope_cmd(&xpc, xpc.xp_pattern, CMD_cscope);
- xpc.xp_pattern_len = (int)STRLEN(xpc.xp_pattern);
- }
+ if (xpc.xp_context == EXPAND_CSCOPE)
+ {
+ set_context_in_cscope_cmd(&xpc, xpc.xp_pattern, CMD_cscope);
+ xpc.xp_pattern_len = (int)STRLEN(xpc.xp_pattern);
+ }
# endif
# ifdef FEAT_SIGNS
- if (xpc.xp_context == EXPAND_SIGN)
- {
- set_context_in_sign_cmd(&xpc, xpc.xp_pattern);
- xpc.xp_pattern_len = (int)STRLEN(xpc.xp_pattern);
- }
+ if (xpc.xp_context == EXPAND_SIGN)
+ {
+ set_context_in_sign_cmd(&xpc, xpc.xp_pattern);
+ xpc.xp_pattern_len = (int)STRLEN(xpc.xp_pattern);
+ }
# endif
+ }
pat = addstar(xpc.xp_pattern, xpc.xp_pattern_len, xpc.xp_context);
if ((rettv_list_alloc(rettv) != FAIL) && (pat != NULL))
diff --git a/src/testdir/test_cmdline.vim b/src/testdir/test_cmdline.vim
index 81350aa..1d3f275 100644
--- a/src/testdir/test_cmdline.vim
+++ b/src/testdir/test_cmdline.vim
@@ -355,6 +355,20 @@
call assert_equal(['Testing'], l)
endif
+ " Command line completion tests
+ let l = getcompletion('cd ', 'cmdline')
+ call assert_true(index(l, 'samples/') >= 0)
+ let l = getcompletion('cd NoMatch', 'cmdline')
+ call assert_equal([], l)
+ let l = getcompletion('let v:n', 'cmdline')
+ call assert_true(index(l, 'v:null') >= 0)
+ let l = getcompletion('let v:notexists', 'cmdline')
+ call assert_equal([], l)
+ let l = getcompletion('call tag', 'cmdline')
+ call assert_true(index(l, 'taglist(') >= 0)
+ let l = getcompletion('call paint', 'cmdline')
+ call assert_equal([], l)
+
" For others test if the name is recognized.
let names = ['buffer', 'environment', 'file_in_path', 'mapping', 'tag', 'tag_listfiles', 'user']
if has('cmdline_hist')
@@ -379,7 +393,7 @@
set tags&
call assert_fails('call getcompletion("", "burp")', 'E475:')
- call assert_fails('call getcompletion("abc", [])', 'E474:')
+ call assert_fails('call getcompletion("abc", [])', 'E475:')
endfunc
func Test_shellcmd_completion()
diff --git a/src/version.c b/src/version.c
index 9e4993d..bfe94cf 100644
--- a/src/version.c
+++ b/src/version.c
@@ -755,6 +755,8 @@
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 925,
+/**/
924,
/**/
923,