# HG changeset patch # User Christian Brabandt # Date 1468083606 -7200 # Node ID cdffa812f9d1cfea65d8f7d94e8f3627870dff84 # Parent b3f970a869d6d83bcd9b0d576f27c9eba397caf0 commit https://github.com/vim/vim/commit/aa4d73235bf4deee167aa5314b89ae3d3db334b7 Author: Bram Moolenaar Date: Sat Jul 9 18:50:29 2016 +0200 patch 7.4.2011 Problem: It is not easy to get a list of command arguments. Solution: Add getcompletion(). (Yegappan Lakshmanan) diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -2008,6 +2008,7 @@ getcmdline() String return the current getcmdpos() Number return cursor position in command-line getcmdtype() String return current command-line type getcmdwintype() String return current command-line window type +getcompletion({pat}, {type}) List list of cmdline completion matches getcurpos() List position of the cursor getcwd([{winnr} [, {tabnr}]]) String get the current working directory getfontname([{name}]) String name of font being used @@ -4044,6 +4045,49 @@ getcmdwintype() *getcmdwintype()* values are the same as |getcmdtype()|. Returns an empty string when not in the command-line window. +getcompletion({pat}, {type}) *getcompletion()* + Return a list of command-line completion matches. {type} + specifies what for. The following completion types are + supported: + + augroup autocmd groups + buffer buffer names + behave :behave suboptions + color color schemes + command Ex command (and arguments) + compiler compilers + cscope |:cscope| suboptions + dir directory names + environment environment variable names + event autocommand events + expression Vim expression + file file and directory names + file_in_path file and directory names in |'path'| + filetype filetype names |'filetype'| + function function name + help help subjects + highlight highlight groups + history :history suboptions + locale locale names (as output of locale -a) + mapping mapping name + menu menus + option options + shellcmd Shell command + sign |:sign| suboptions + syntax syntax file names |'syntax'| + syntime |:syntime| suboptions + tag tags + tag_listfiles tags, file names + 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 there are no matches, an empty list is returned. An + invalid value for {type} produces an error. + *getcurpos()* getcurpos() Get the position of the cursor. This is like getpos('.'), but includes an extra item in the list: diff --git a/src/eval.c b/src/eval.c --- a/src/eval.c +++ b/src/eval.c @@ -593,6 +593,9 @@ static void f_getchar(typval_T *argvars, static void f_getcharmod(typval_T *argvars, typval_T *rettv); static void f_getcharsearch(typval_T *argvars, typval_T *rettv); static void f_getcmdline(typval_T *argvars, typval_T *rettv); +#if defined(FEAT_CMDL_COMPL) +static void f_getcompletion(typval_T *argvars, typval_T *rettv); +#endif static void f_getcmdpos(typval_T *argvars, typval_T *rettv); static void f_getcmdtype(typval_T *argvars, typval_T *rettv); static void f_getcmdwintype(typval_T *argvars, typval_T *rettv); @@ -8606,6 +8609,9 @@ static struct fst {"getcmdpos", 0, 0, f_getcmdpos}, {"getcmdtype", 0, 0, f_getcmdtype}, {"getcmdwintype", 0, 0, f_getcmdwintype}, +#if defined(FEAT_CMDL_COMPL) + {"getcompletion", 2, 2, f_getcompletion}, +#endif {"getcurpos", 0, 0, f_getcurpos}, {"getcwd", 0, 2, f_getcwd}, {"getfontname", 0, 1, f_getfontname}, @@ -13083,6 +13089,55 @@ f_getcmdwintype(typval_T *argvars UNUSED #endif } +#if defined(FEAT_CMDL_COMPL) +/* + * "getcompletion()" function + */ + static void +f_getcompletion(typval_T *argvars, typval_T *rettv) +{ + char_u *pat; + expand_T xpc; + int options = WILD_KEEP_ALL | WILD_SILENT | WILD_USE_NL + | WILD_LIST_NOTFOUND | WILD_NO_BEEP; + + if (p_wic) + options |= WILD_ICASE; + + ExpandInit(&xpc); + xpc.xp_pattern = get_tv_string(&argvars[0]); + xpc.xp_pattern_len = STRLEN(xpc.xp_pattern); + xpc.xp_context = cmdcomplete_str_to_type(get_tv_string(&argvars[1])); + if (xpc.xp_context == EXPAND_NOTHING) + { + if (argvars[1].v_type == VAR_STRING) + EMSG2(_(e_invarg2), argvars[1].vval.v_string); + else + EMSG(_(e_invarg)); + return; + } + + if (xpc.xp_context == EXPAND_MENUS) + { + set_context_in_menu_cmd(&xpc, (char_u *)"menu", xpc.xp_pattern, FALSE); + xpc.xp_pattern_len = STRLEN(xpc.xp_pattern); + } + + pat = addstar(xpc.xp_pattern, xpc.xp_pattern_len, xpc.xp_context); + if ((rettv_list_alloc(rettv) != FAIL) && (pat != NULL)) + { + int i; + + ExpandOne(&xpc, pat, NULL, options, WILD_ALL_KEEP); + + for (i = 0; i < xpc.xp_numfiles; i++) + list_append_string(rettv->vval.v_list, xpc.xp_files[i], -1); + } + vim_free(pat); + ExpandCleanup(&xpc); +} +#endif + /* * "getcwd()" function */ diff --git a/src/ex_docmd.c b/src/ex_docmd.c --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -7049,6 +7049,18 @@ parse_compl_arg( # endif return OK; } + + int +cmdcomplete_str_to_type(char_u *complete_str) +{ + int i; + + for (i = 0; command_complete[i].expand != 0; ++i) + if (STRCMP(complete_str, command_complete[i].name) == 0) + return command_complete[i].expand; + + return EXPAND_NOTHING; +} #endif static void diff --git a/src/proto/ex_docmd.pro b/src/proto/ex_docmd.pro --- a/src/proto/ex_docmd.pro +++ b/src/proto/ex_docmd.pro @@ -25,6 +25,7 @@ char_u *get_user_cmd_nargs(expand_T *xp, char_u *get_user_cmd_complete(expand_T *xp, int idx); int parse_addr_type_arg(char_u *value, int vallen, long *argt, int *addr_type_arg); int parse_compl_arg(char_u *value, int vallen, int *complp, long *argt, char_u **compl_arg); +int cmdcomplete_str_to_type(char_u *complete_str); void not_exiting(void); void tabpage_close(int forceit); void tabpage_close_other(tabpage_T *tp, int forceit); diff --git a/src/testdir/test_cmdline.vim b/src/testdir/test_cmdline.vim --- a/src/testdir/test_cmdline.vim +++ b/src/testdir/test_cmdline.vim @@ -24,3 +24,19 @@ func Test_complete_wildmenu() call delete('Xtestfile2') set nowildmenu endfunc + +func Test_getcompletion() + let groupcount = len(getcompletion('', 'event')) + call assert_true(groupcount > 0) + let matchcount = len(getcompletion('File', 'event')) + call assert_true(matchcount > 0) + call assert_true(groupcount > matchcount) + + source $VIMRUNTIME/menu.vim + let matchcount = len(getcompletion('', 'menu')) + call assert_true(matchcount > 0) + let matchcount = len(getcompletion('ToolBar.', 'menu')) + call assert_true(matchcount > 0) + + call assert_fails('call getcompletion("", "burp")', 'E475:') +endfunc diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -759,6 +759,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 2011, +/**/ 2010, /**/ 2009,