]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.1.1340: cannot complete :filetype arguments v9.1.1340
authorChristian Brabandt <cb@256bit.org>
Wed, 23 Apr 2025 19:04:24 +0000 (21:04 +0200)
committerChristian Brabandt <cb@256bit.org>
Wed, 23 Apr 2025 19:12:26 +0000 (21:12 +0200)
Problem:  cannot complete :filetype arguments (Phạm Bình An)
Solution: add :filetype ex command completion, add "filetypecmd"
          completion type for getcompletion()

fixes: #17165
closes: #17167

Co-authored-by: zeertzjq <zeertzjq@outlook.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
runtime/doc/builtin.txt
runtime/doc/version9.txt
src/cmdexpand.c
src/testdir/test_cmdline.vim
src/usercmd.c
src/version.c
src/vim.h

index 0a1c3b12720ee2aef5535780d6e35b34d6b68a34..e6747adcfdb6f3d16486d458510a3fbab75af0c1 100644 (file)
@@ -4270,6 +4270,7 @@ getcompletion({pat}, {type} [, {filtered}])               *getcompletion()*
                file            file and directory names
                file_in_path    file and directory names in |'path'|
                filetype        filetype names |'filetype'|
+               filetypecmd     |:filetype| suboptions
                function        function name
                help            help subjects
                highlight       highlight groups
index 1ef04bd2efa413a7af7f329e92d9bb78bca786d9..dfbe457a262ad6a0c9fba1313f26bef2fa823f43 100644 (file)
@@ -1,4 +1,4 @@
-*version9.txt*  For Vim version 9.1.  Last change: 2025 Apr 21
+*version9.txt*  For Vim version 9.1.  Last change: 2025 Apr 23
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -41624,6 +41624,8 @@ Completion: ~
        "o"             - complete using 'omnifunc'
 - allow to limit matches for the 'complete' sources by using the
   "{flag}^<limit>" notation
+- add ":filetype" command completion
+- add "filetypecmd" completion type for |getcompletion()|
 
 Options: ~
 - the default for 'commentstring' contains whitespace padding to have
index 4dbd10ee8a7ab4e6871ce6d8a1cb88f0e3787e92..f7d3ac8c9885686189cdc437ff9551b67834a575 100644 (file)
@@ -53,6 +53,7 @@ cmdline_fuzzy_completion_supported(expand_T *xp)
            && xp->xp_context != EXPAND_FILES
            && xp->xp_context != EXPAND_FILES_IN_PATH
            && xp->xp_context != EXPAND_FILETYPE
+           && xp->xp_context != EXPAND_FILETYPECMD
            && xp->xp_context != EXPAND_FINDFUNC
            && xp->xp_context != EXPAND_HELP
            && xp->xp_context != EXPAND_KEYMAP
@@ -2058,6 +2059,18 @@ set_context_in_lang_cmd(expand_T *xp, char_u *arg)
 }
 #endif
 
+static enum
+{
+    EXP_FILETYPECMD_ALL,       // expand all :filetype values
+    EXP_FILETYPECMD_PLUGIN,    // expand plugin on off
+    EXP_FILETYPECMD_INDENT,    // expand indent on off
+    EXP_FILETYPECMD_ONOFF,     // expand on off
+} filetype_expand_what;
+
+#define EXPAND_FILETYPECMD_PLUGIN 0x01
+#define EXPAND_FILETYPECMD_INDENT 0x02
+#define EXPAND_FILETYPECMD_ONOFF  0x04
+
 #ifdef FEAT_EVAL
 static enum
 {
@@ -2143,6 +2156,53 @@ set_context_in_scriptnames_cmd(expand_T *xp, char_u *arg)
 }
 #endif
 
+/*
+ * Set the completion context for the :filetype command. Always returns NULL.
+ */
+    static char_u *
+set_context_in_filetype_cmd(expand_T *xp, char_u *arg)
+{
+    char_u *p;
+    int    val = 0;
+
+    xp->xp_context = EXPAND_FILETYPECMD;
+    xp->xp_pattern = arg;
+    filetype_expand_what = EXP_FILETYPECMD_ALL;
+
+    p = skipwhite(arg);
+    if (*p == NUL)
+       return NULL;
+
+    for (;;)
+    {
+       if (STRNCMP(p, "plugin", 6) == 0)
+       {
+           val |= EXPAND_FILETYPECMD_PLUGIN;
+           p = skipwhite(p + 6);
+           continue;
+       }
+       if (STRNCMP(p, "indent", 6) == 0)
+       {
+           val |= EXPAND_FILETYPECMD_INDENT;
+           p = skipwhite(p + 6);
+           continue;
+       }
+       break;
+    }
+
+    if ((val & EXPAND_FILETYPECMD_PLUGIN) && (val & EXPAND_FILETYPECMD_INDENT))
+       filetype_expand_what = EXP_FILETYPECMD_ONOFF;
+    else if ((val & EXPAND_FILETYPECMD_PLUGIN))
+       filetype_expand_what = EXP_FILETYPECMD_INDENT;
+    else if ((val & EXPAND_FILETYPECMD_INDENT))
+       filetype_expand_what = EXP_FILETYPECMD_PLUGIN;
+
+    xp->xp_pattern = p;
+
+    return NULL;
+}
+
+
 /*
  * Set the completion context in 'xp' for command 'cmd' with index 'cmdidx'.
  * The argument to the command is 'arg' and the argument flags is 'argt'.
@@ -2515,6 +2575,8 @@ set_context_by_cmdname(
        case CMD_scriptnames:
            return set_context_in_scriptnames_cmd(xp, arg);
 #endif
+       case CMD_filetype:
+           return set_context_in_filetype_cmd(xp, arg);
 
        default:
            break;
@@ -2949,6 +3011,29 @@ get_behave_arg(expand_T *xp UNUSED, int idx)
     return NULL;
 }
 
+/*
+ * Function given to ExpandGeneric() to obtain the possible arguments of the
+ * ":filetype {plugin,indent}" command.
+ */
+    static char_u *
+get_filetypecmd_arg(expand_T *xp UNUSED, int idx)
+{
+    char *opts_all[] = {"indent", "plugin", "on", "off"};
+    char *opts_plugin[] = {"plugin", "on", "off"};
+    char *opts_indent[] = {"indent", "on", "off"};
+    char *opts_onoff[] = {"on", "off"};
+
+    if (filetype_expand_what == EXP_FILETYPECMD_ALL && idx < 4)
+       return (char_u *)opts_all[idx];
+    if (filetype_expand_what == EXP_FILETYPECMD_PLUGIN && idx < 3)
+       return (char_u *)opts_plugin[idx];
+    if (filetype_expand_what == EXP_FILETYPECMD_INDENT && idx < 3)
+       return (char_u *)opts_indent[idx];
+    if (filetype_expand_what == EXP_FILETYPECMD_ONOFF && idx < 2)
+       return (char_u *)opts_onoff[idx];
+    return NULL;
+}
+
 #ifdef FEAT_EVAL
 /*
  * Function given to ExpandGeneric() to obtain the possible arguments of the
@@ -3040,6 +3125,7 @@ ExpandOther(
     {
        {EXPAND_COMMANDS, get_command_name, FALSE, TRUE},
        {EXPAND_BEHAVE, get_behave_arg, TRUE, TRUE},
+       {EXPAND_FILETYPECMD, get_filetypecmd_arg, TRUE, TRUE},
        {EXPAND_MAPCLEAR, get_mapclear_arg, TRUE, TRUE},
        {EXPAND_MESSAGES, get_messages_arg, TRUE, TRUE},
        {EXPAND_HISTORY, get_history_arg, TRUE, TRUE},
@@ -4295,6 +4381,8 @@ f_getcompletion(typval_T *argvars, typval_T *rettv)
                                                                     &context);
            xpc.xp_pattern_len = (int)STRLEN(xpc.xp_pattern);
        }
+       if (xpc.xp_context == EXPAND_FILETYPECMD)
+           filetype_expand_what = EXP_FILETYPECMD_ALL;
     }
 
     if (cmdline_fuzzy_completion_supported(&xpc))
index c66a4273e327d72950362982f25ddd83033915ba..c4b7b5743efccb47475b43fcea98220c30732142 100644 (file)
@@ -684,6 +684,13 @@ func Test_getcompletion()
   let l = getcompletion('kill', 'expression')
   call assert_equal([], l)
 
+  let l = getcompletion('', 'filetypecmd')
+  call assert_equal(["indent", "off", "on", "plugin"], l)
+  let l = getcompletion('not', 'filetypecmd')
+  call assert_equal([], l)
+  let l = getcompletion('o', 'filetypecmd')
+  call assert_equal(['off', 'on'], l)
+
   let l = getcompletion('tag', 'function')
   call assert_true(index(l, 'taglist(') >= 0)
   let l = getcompletion('paint', 'function')
@@ -3209,6 +3216,26 @@ func Test_fuzzy_completion_behave()
   set wildoptions&
 endfunc
 
+" :filetype suboptions completion
+func Test_completion_filetypecmd()
+  set wildoptions&
+  call feedkeys(":filetype \<C-A>\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"filetype indent off on plugin', @:)
+  call feedkeys(":filetype plugin \<C-A>\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"filetype plugin indent off on', @:)
+  call feedkeys(":filetype indent \<C-A>\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"filetype indent off on plugin', @:)
+  call feedkeys(":filetype i\<C-A>\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"filetype indent', @:)
+  call feedkeys(":filetype p\<C-A>\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"filetype plugin', @:)
+  call feedkeys(":filetype o\<C-A>\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"filetype off on', @:)
+  call feedkeys(":filetype indent of\<C-A>\<C-B>\"\<CR>", 'tx')
+  call assert_equal('"filetype indent off', @:)
+  set wildoptions&
+endfunc
+
 " " colorscheme name fuzzy completion - NOT supported
 " func Test_fuzzy_completion_colorscheme()
 " endfunc
index ff2c353e39205566d71c337e779eb377d68770a6..fafa97d15f248e7561e2b5d458e01a19ec809ad1 100644 (file)
@@ -71,6 +71,7 @@ static keyvalue_T command_complete_tab[] =
     KEYVALUE_ENTRY(EXPAND_FILES, "file"),
     KEYVALUE_ENTRY(EXPAND_FILES_IN_PATH, "file_in_path"),
     KEYVALUE_ENTRY(EXPAND_FILETYPE, "filetype"),
+    KEYVALUE_ENTRY(EXPAND_FILETYPECMD, "filetypecmd"),
     KEYVALUE_ENTRY(EXPAND_FUNCTIONS, "function"),
     KEYVALUE_ENTRY(EXPAND_HELP, "help"),
     KEYVALUE_ENTRY(EXPAND_HIGHLIGHT, "highlight"),
index d9b6e71b2074e3e593b0974334fe925ea08248b6..417088bfa2e6e3d998e54c40747f7c2b290fc0ba 100644 (file)
@@ -704,6 +704,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1340,
 /**/
     1339,
 /**/
index 41984dadc5a390f79be3ec82d069052dbcf45926..fbe5c341958ef936246792946b1a04f65a67e8a7 100644 (file)
--- a/src/vim.h
+++ b/src/vim.h
@@ -854,6 +854,7 @@ extern int (*dyn_libintl_wputenv)(const wchar_t *envstring);
 #define EXPAND_SHELLCMDLINE    60
 #define EXPAND_FINDFUNC                61
 #define EXPAND_HIGHLIGHT_GROUP  62
+#define EXPAND_FILETYPECMD     63
 
 
 // Values for exmode_active (0 is no exmode)