patch 9.1.1340: cannot complete :filetype arguments Commit: https://github.com/vim/vim/commit/a3422aa3170d49a7c3d1e6cd4242b86e42ef3945 Author: Christian Brabandt <c...@256bit.org> Date: Wed Apr 23 21:04:24 2025 +0200
patch 9.1.1340: cannot complete :filetype arguments 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 <zeert...@outlook.com> Signed-off-by: Christian Brabandt <c...@256bit.org> diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt index 0a1c3b127..e6747adcf 100644 --- a/runtime/doc/builtin.txt +++ b/runtime/doc/builtin.txt @@ -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 diff --git a/runtime/doc/version9.txt b/runtime/doc/version9.txt index 1ef04bd2e..dfbe457a2 100644 --- a/runtime/doc/version9.txt +++ b/runtime/doc/version9.txt @@ -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 diff --git a/src/cmdexpand.c b/src/cmdexpand.c index 4dbd10ee8..f7d3ac8c9 100644 --- a/src/cmdexpand.c +++ b/src/cmdexpand.c @@ -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)) diff --git a/src/testdir/test_cmdline.vim b/src/testdir/test_cmdline.vim index c66a4273e..c4b7b5743 100644 --- a/src/testdir/test_cmdline.vim +++ b/src/testdir/test_cmdline.vim @@ -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 diff --git a/src/usercmd.c b/src/usercmd.c index ff2c353e3..fafa97d15 100644 --- a/src/usercmd.c +++ b/src/usercmd.c @@ -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"), diff --git a/src/version.c b/src/version.c index d9b6e71b2..417088bfa 100644 --- a/src/version.c +++ b/src/version.c @@ -704,6 +704,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1340, /**/ 1339, /**/ diff --git a/src/vim.h b/src/vim.h index 41984dadc..fbe5c3419 100644 --- 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) -- -- You received this message from the "vim_dev" maillist. Do not top-post! Type your reply below the text you are replying to. For more information, visit http://www.vim.org/maillist.php --- You received this message because you are subscribed to the Google Groups "vim_dev" group. To unsubscribe from this group and stop receiving emails from it, send an email to vim_dev+unsubscr...@googlegroups.com. To view this discussion visit https://groups.google.com/d/msgid/vim_dev/E1u7fnH-003aNN-NL%40256bit.org.