aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShougo Matsushita <Shougo.Matsu@gmail.com>2016-07-23 11:33:38 +0900
committerJustin M. Keyes <justinkz@gmail.com>2016-08-01 03:33:38 -0400
commit23f591dba078fee16ab6e4debfcd051e799ca4f8 (patch)
tree0a469e39398562b3145821b8b9b1ed124e9b48a1
parent70ae6ac344472e51ac75316992e2c03464b4f6ad (diff)
downloadrneovim-23f591dba078fee16ab6e4debfcd051e799ca4f8.tar.gz
rneovim-23f591dba078fee16ab6e4debfcd051e799ca4f8.tar.bz2
rneovim-23f591dba078fee16ab6e4debfcd051e799ca4f8.zip
[RFC] vim-patch:7.4.2011, vim-patch:7.4.2012, vim-patch:7.4.2066 #5106
vim-patch:7.4.2011 Problem: It is not easy to get a list of command arguments. Solution: Add getcompletion(). (Yegappan Lakshmanan) https://github.com/vim/vim/commit/aa4d73235bf4deee167aa5314b89ae3d3db334b7 vim-patch:7.4.2012 Problem: Test for getcompletion() does not pass on all systems. Solution: Only test what is supported. https://github.com/vim/vim/commit/0d3e24be5686c0710aa3c6671e4c626d6cb21a5f vim-patch:7.4.2066 Problem: getcompletion() not well tested. Solution: Add more testing. https://github.com/vim/vim/commit/c1fb763184c8ae82300357867fa2070aa94366e9
-rw-r--r--runtime/doc/eval.txt44
-rw-r--r--src/nvim/eval.c45
-rw-r--r--src/nvim/ex_docmd.c11
-rw-r--r--src/nvim/testdir/test_alot.vim1
-rw-r--r--src/nvim/testdir/test_cmdline.vim120
-rw-r--r--src/nvim/version.c6
6 files changed, 224 insertions, 3 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 9ff97436bb..de1ced160c 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -1887,6 +1887,7 @@ getcmdline() String return the current command-line
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 the current working directory
getfontname([{name}]) String name of font being used
@@ -3647,6 +3648,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/nvim/eval.c b/src/nvim/eval.c
index 824b298592..8a96278673 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -6791,6 +6791,7 @@ static struct fst {
{ "getcmdpos", 0, 0, f_getcmdpos },
{ "getcmdtype", 0, 0, f_getcmdtype },
{ "getcmdwintype", 0, 0, f_getcmdwintype },
+ { "getcompletion", 2, 2, f_getcompletion },
{ "getcurpos", 0, 0, f_getcurpos },
{ "getcwd", 0, 2, f_getcwd },
{ "getfontname", 0, 1, f_getfontname },
@@ -9983,6 +9984,50 @@ static void f_getcmdwintype(typval_T *argvars, typval_T *rettv)
rettv->vval.v_string[0] = cmdwin_type;
}
+// "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);
+ }
+ }
+ xfree(pat);
+ ExpandCleanup(&xpc);
+}
+
/// `getcwd([{win}[, {tab}]])` function
///
/// Every scope not specified implies the currently selected scope object.
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 9bc7ec39da..8bae817211 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -5597,6 +5597,17 @@ int parse_compl_arg(char_u *value, int vallen, int *complp,
return OK;
}
+int cmdcomplete_str_to_type(char_u *complete_str)
+{
+ for (int 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;
+}
+
static void ex_colorscheme(exarg_T *eap)
{
if (*eap->arg == NUL) {
diff --git a/src/nvim/testdir/test_alot.vim b/src/nvim/testdir/test_alot.vim
index 14ea73818a..30b8a9ceb8 100644
--- a/src/nvim/testdir/test_alot.vim
+++ b/src/nvim/testdir/test_alot.vim
@@ -3,6 +3,7 @@
source test_assign.vim
source test_cursor_func.vim
+source test_cmdline.vim
source test_menu.vim
source test_popup.vim
source test_unlet.vim
diff --git a/src/nvim/testdir/test_cmdline.vim b/src/nvim/testdir/test_cmdline.vim
new file mode 100644
index 0000000000..438b20cc5e
--- /dev/null
+++ b/src/nvim/testdir/test_cmdline.vim
@@ -0,0 +1,120 @@
+" Tests for editing the command line.
+
+func Test_complete_tab()
+ call writefile(['testfile'], 'Xtestfile')
+ call feedkeys(":e Xtest\t\r", "tx")
+ call assert_equal('testfile', getline(1))
+ call delete('Xtestfile')
+endfunc
+
+func Test_complete_list()
+ " We can't see the output, but at least we check the code runs properly.
+ call feedkeys(":e test\<C-D>\r", "tx")
+ call assert_equal('test', expand('%:t'))
+endfunc
+
+func Test_complete_wildmenu()
+ call writefile(['testfile1'], 'Xtestfile1')
+ call writefile(['testfile2'], 'Xtestfile2')
+ set wildmenu
+ call feedkeys(":e Xtest\t\t\r", "tx")
+ call assert_equal('testfile2', getline(1))
+
+ call delete('Xtestfile1')
+ call delete('Xtestfile2')
+ set nowildmenu
+endfunc
+
+func Test_getcompletion()
+ if !has('cmdline_compl')
+ return
+ endif
+ 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)
+
+ if has('menu')
+ source $VIMRUNTIME/menu.vim
+ let matchcount = len(getcompletion('', 'menu'))
+ call assert_true(matchcount > 0)
+ call assert_equal(['File.'], getcompletion('File', 'menu'))
+ call assert_true(matchcount > 0)
+ let matchcount = len(getcompletion('File.', 'menu'))
+ call assert_true(matchcount > 0)
+ endif
+
+ let l = getcompletion('v:n', 'var')
+ call assert_true(index(l, 'v:null') >= 0)
+
+ let l = getcompletion('', 'augroup')
+ call assert_true(index(l, 'END') >= 0)
+
+ let l = getcompletion('', 'behave')
+ call assert_true(index(l, 'mswin') >= 0)
+
+ let l = getcompletion('', 'color')
+ call assert_true(index(l, 'default') >= 0)
+
+ let l = getcompletion('', 'command')
+ call assert_true(index(l, 'sleep') >= 0)
+
+ let l = getcompletion('', 'dir')
+ call assert_true(index(l, 'sautest') >= 0)
+
+ let l = getcompletion('exe', 'expression')
+ call assert_true(index(l, 'executable(') >= 0)
+
+ let l = getcompletion('tag', 'function')
+ call assert_true(index(l, 'taglist(') >= 0)
+
+ let l = getcompletion('run', 'file')
+ call assert_true(index(l, 'runtest.vim') >= 0)
+
+ let l = getcompletion('ha', 'filetype')
+ call assert_true(index(l, 'hamster') >= 0)
+
+ let l = getcompletion('z', 'syntax')
+ call assert_true(index(l, 'zimbu') >= 0)
+
+ let l = getcompletion('jikes', 'compiler')
+ call assert_true(index(l, 'jikes') >= 0)
+
+ let l = getcompletion('time', 'option')
+ call assert_true(index(l, 'timeoutlen') >= 0)
+
+ let l = getcompletion('er', 'highlight')
+ call assert_true(index(l, 'ErrorMsg') >= 0)
+
+ " For others test if the name is recognized.
+ let names = ['buffer', 'environment', 'file_in_path',
+ \ 'mapping', 'shellcmd', 'tag', 'tag_listfiles', 'user']
+ if has('cscope')
+ call add(names, 'cscope')
+ endif
+ if has('cmdline_hist')
+ call add(names, 'history')
+ endif
+ if has('gettext')
+ call add(names, 'locale')
+ endif
+ if has('profile')
+ call add(names, 'syntime')
+ endif
+ if has('signs')
+ call add(names, 'sign')
+ endif
+
+ set tags=Xtags
+ call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//", "word\tfile\tcmd"], 'Xtags')
+
+ for name in names
+ let matchcount = len(getcompletion('', name))
+ call assert_true(matchcount >= 0, 'No matches for ' . name)
+ endfor
+
+ call delete('Xtags')
+
+ call assert_fails('call getcompletion("", "burp")', 'E475:')
+endfunc
diff --git a/src/nvim/version.c b/src/nvim/version.c
index bd6b1af901..0ec41787ed 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -209,7 +209,7 @@ static int included_patches[] = {
// 2069,
// 2068,
// 2067,
- // 2066,
+ 2066,
// 2065,
// 2064,
// 2063 NA
@@ -263,8 +263,8 @@ static int included_patches[] = {
// 2015,
2014,
2013,
- // 2012,
- // 2011,
+ 2012,
+ 2011,
// 2010,
// 2009,
// 2008,