]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.0.1774: no support for custom cmdline completion v9.0.1774
authorShougo Matsushita <Shougo.Matsu@gmail.com>
Sun, 20 Aug 2023 18:55:55 +0000 (20:55 +0200)
committerChristian Brabandt <cb@256bit.org>
Sun, 20 Aug 2023 18:55:55 +0000 (20:55 +0200)
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>
runtime/doc/builtin.txt
src/cmdexpand.c
src/ex_getln.c
src/testdir/test_cmdline.vim
src/usercmd.c
src/version.c

index 661876b24a430b64f47092f9f736f8f01a0f89f2..e9bdad2edf7d95d2871d2584f35600c5944841ba 100644 (file)
@@ -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
index b8c2711b28fe373496ac6df1eeabc819ca47353b..6ffef0c3e748de952d79c04cbb91420678b5435d 100644 (file)
@@ -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)
        {
index dff7ec9ff5e642be389f87b503e305890d7a3ab4..88eba32b80cbfd3154b14da5e0fd396a225b2d3f 100644 (file)
@@ -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);
 }
 
 /*
index b5dec06956f17e772ec31af465ec09efbb567b4b..b2566cdfb1aad43528cb2f54ecfc1ce8eb49ca3c 100644 (file)
@@ -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
index 57435fafbc2a8870f82636ec8235332aa6d9ee57..31912578091dad62a39db092187c9d4197f5b39d 100644 (file)
@@ -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;
index ffecee9e1791fc488aff721c93b84b711ccd76f5..dbe15f83b45d8f3f71eaf7e01bd18c5159ba3fca 100644 (file)
@@ -695,6 +695,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1774,
 /**/
     1773,
 /**/