summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShougo Matsushita <Shougo.Matsu@gmail.com>2023-08-20 20:55:55 +0200
committerChristian Brabandt <cb@256bit.org>2023-08-20 20:55:55 +0200
commit92997dda789ad8061841128cbc99b15ec0374411 (patch)
tree47a00691b428554c6d6bba0126e7b3874d28b135
parent19a3bc3addf9b4aa8150a01b11b4249c67d15d3b (diff)
patch 9.0.1774: no support for custom cmdline completionv9.0.1774
Problem: no support for custom cmdline completion Solution: Add new vimscript functions Add the following two functions: - getcmdcompltype() returns custom and customlist functions - getcompletion() supports both custom and customlist closes: #12228 Signed-off-by: Christian Brabandt <cb@256bit.org> Co-authored-by: Shougo Matsushita <Shougo.Matsu@gmail.com>
-rw-r--r--runtime/doc/builtin.txt2
-rw-r--r--src/cmdexpand.c25
-rw-r--r--src/ex_getln.c16
-rw-r--r--src/testdir/test_cmdline.vim38
-rw-r--r--src/usercmd.c5
-rw-r--r--src/version.c2
6 files changed, 85 insertions, 3 deletions
diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt
index 661876b24a..e9bdad2edf 100644
--- a/runtime/doc/builtin.txt
+++ b/runtime/doc/builtin.txt
@@ -3551,6 +3551,8 @@ getcompletion({pat}, {type} [, {filtered}]) *getcompletion()*
cmdline |cmdline-completion| result
compiler compilers
cscope |:cscope| suboptions
+ custom,{func} custom completion, defined via {func}
+ customlist,{func} custom completion, defined via {func}
diff_buffer |:diffget| and |:diffput| completion
dir directory names
environment environment variable names
diff --git a/src/cmdexpand.c b/src/cmdexpand.c
index b8c2711b28..6ffef0c3e7 100644
--- a/src/cmdexpand.c
+++ b/src/cmdexpand.c
@@ -4022,6 +4022,7 @@ f_getcompletion(typval_T *argvars, typval_T *rettv)
{
xpc.xp_pattern = pat;
xpc.xp_pattern_len = (int)STRLEN(xpc.xp_pattern);
+ xpc.xp_line = pat;
xpc.xp_context = cmdcomplete_str_to_type(type);
if (xpc.xp_context == EXPAND_NOTHING)
@@ -4030,6 +4031,30 @@ f_getcompletion(typval_T *argvars, typval_T *rettv)
return;
}
+ if (xpc.xp_context == EXPAND_USER_DEFINED)
+ {
+ // Must be "custom,funcname" pattern
+ if (STRNCMP(type, "custom,", 7) != 0)
+ {
+ semsg(_(e_invalid_argument_str), type);
+ return;
+ }
+
+ xpc.xp_arg = type + 7;
+ }
+
+ if (xpc.xp_context == EXPAND_USER_LIST)
+ {
+ // Must be "customlist,funcname" pattern
+ if (STRNCMP(type, "customlist,", 11) != 0)
+ {
+ semsg(_(e_invalid_argument_str), type);
+ return;
+ }
+
+ xpc.xp_arg = type + 11;
+ }
+
# if defined(FEAT_MENU)
if (xpc.xp_context == EXPAND_MENUS)
{
diff --git a/src/ex_getln.c b/src/ex_getln.c
index dff7ec9ff5..88eba32b80 100644
--- a/src/ex_getln.c
+++ b/src/ex_getln.c
@@ -4152,6 +4152,7 @@ get_cmdline_str(void)
get_cmdline_completion(void)
{
cmdline_info_T *p;
+ char_u *buffer;
if (cmdline_star > 0)
return NULL;
@@ -4165,10 +4166,19 @@ get_cmdline_completion(void)
return NULL;
char_u *cmd_compl = cmdcomplete_type_to_str(p->xpc->xp_context);
- if (cmd_compl != NULL)
- return vim_strsave(cmd_compl);
+ if (cmd_compl == NULL)
+ return NULL;
- return NULL;
+ if (p->xpc->xp_context == EXPAND_USER_LIST || p->xpc->xp_context == EXPAND_USER_DEFINED)
+ {
+ buffer = alloc(STRLEN(cmd_compl) + STRLEN(p->xpc->xp_arg) + 2);
+ if (buffer == NULL)
+ return NULL;
+ sprintf((char *)buffer, "%s,%s", cmd_compl, p->xpc->xp_arg);
+ return buffer;
+ }
+
+ return vim_strsave(cmd_compl);
}
/*
diff --git a/src/testdir/test_cmdline.vim b/src/testdir/test_cmdline.vim
index b5dec06956..b2566cdfb1 100644
--- a/src/testdir/test_cmdline.vim
+++ b/src/testdir/test_cmdline.vim
@@ -3511,4 +3511,42 @@ func Test_getcompletion_usercmd()
delcom TestCompletion
endfunc
+func Test_custom_completion()
+ func CustomComplete1(lead, line, pos)
+ return "a\nb\nc"
+ endfunc
+ func CustomComplete2(lead, line, pos)
+ return ['a', 'b']->filter({ _, val -> val->stridx(a:lead) == 0 })
+ endfunc
+ func Check_custom_completion()
+ call assert_equal('custom,CustomComplete1', getcmdcompltype())
+ return ''
+ endfunc
+ func Check_customlist_completion()
+ call assert_equal('customlist,CustomComplete2', getcmdcompltype())
+ return ''
+ endfunc
+
+ command -nargs=1 -complete=custom,CustomComplete1 Test1 echo
+ command -nargs=1 -complete=customlist,CustomComplete2 Test2 echo
+
+ call feedkeys(":Test1 \<C-R>=Check_custom_completion()\<CR>\<Esc>", "xt")
+ call feedkeys(":Test2 \<C-R>=Check_customlist_completion()\<CR>\<Esc>", "xt")
+
+ call assert_fails("call getcompletion('', 'custom')", 'E475:')
+ call assert_fails("call getcompletion('', 'customlist')", 'E475:')
+
+ call assert_equal(getcompletion('', 'custom,CustomComplete1'), ['a', 'b', 'c'])
+ call assert_equal(getcompletion('', 'customlist,CustomComplete2'), ['a', 'b'])
+ call assert_equal(getcompletion('b', 'customlist,CustomComplete2'), ['b'])
+
+ delcom Test1
+ delcom Test2
+
+ delfunc CustomComplete1
+ delfunc CustomComplete2
+ delfunc Check_custom_completion
+ delfunc Check_customlist_completion
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/usercmd.c b/src/usercmd.c
index 57435fafbc..3191257809 100644
--- a/src/usercmd.c
+++ b/src/usercmd.c
@@ -481,6 +481,11 @@ cmdcomplete_str_to_type(char_u *complete_str)
{
int i;
+ if (STRNCMP(complete_str, "custom,", 7) == 0)
+ return EXPAND_USER_DEFINED;
+ if (STRNCMP(complete_str, "customlist,", 11) == 0)
+ return EXPAND_USER_LIST;
+
for (i = 0; command_complete[i].expand != 0; ++i)
if (STRCMP(complete_str, command_complete[i].name) == 0)
return command_complete[i].expand;
diff --git a/src/version.c b/src/version.c
index ffecee9e17..dbe15f83b4 100644
--- a/src/version.c
+++ b/src/version.c
@@ -696,6 +696,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1774,
+/**/
1773,
/**/
1772,