mirror of
https://github.com/neovim/neovim
synced 2025-07-16 01:01:49 +00:00
vim-patch:9.1.1340: cannot complete :filetype arguments (#33602)
Problem: cannot complete :filetype arguments (Phạm Bình An)
Solution: add :filetype ex command completion, add "filetypecmd"
completion type for getcompletion()
fixes: vim/vim#17165
closes: vim/vim#17167
a3422aa317
Co-authored-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
1
runtime/doc/builtin.txt
generated
1
runtime/doc/builtin.txt
generated
@ -3401,6 +3401,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
|
||||
|
1
runtime/lua/vim/_meta/vimfn.lua
generated
1
runtime/lua/vim/_meta/vimfn.lua
generated
@ -3048,6 +3048,7 @@ function vim.fn.getcmdwintype() end
|
||||
--- 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
|
||||
|
@ -110,6 +110,7 @@ static bool cmdline_fuzzy_completion_supported(const expand_T *const 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
|
||||
@ -1764,6 +1765,19 @@ static const char *set_context_in_lang_cmd(expand_T *xp, const char *arg)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
enum {
|
||||
EXPAND_FILETYPECMD_PLUGIN = 0x01,
|
||||
EXPAND_FILETYPECMD_INDENT = 0x02,
|
||||
EXPAND_FILETYPECMD_ONOFF = 0x04,
|
||||
};
|
||||
|
||||
static enum {
|
||||
EXP_BREAKPT_ADD, ///< expand ":breakadd" sub-commands
|
||||
EXP_BREAKPT_DEL, ///< expand ":breakdel" sub-commands
|
||||
@ -1836,6 +1850,47 @@ static const char *set_context_in_scriptnames_cmd(expand_T *xp, const char *arg)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/// Set the completion context for the :filetype command. Always returns NULL.
|
||||
static const char *set_context_in_filetype_cmd(expand_T *xp, const char *arg)
|
||||
{
|
||||
xp->xp_context = EXPAND_FILETYPECMD;
|
||||
xp->xp_pattern = (char *)arg;
|
||||
filetype_expand_what = EXP_FILETYPECMD_ALL;
|
||||
|
||||
char *p = skipwhite(arg);
|
||||
if (*p == NUL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int val = 0;
|
||||
|
||||
while (true) {
|
||||
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".
|
||||
/// For user-defined commands and for environment variables, "context" has the
|
||||
@ -2198,6 +2253,9 @@ static const char *set_context_by_cmdname(const char *cmd, cmdidx_T cmdidx, expa
|
||||
case CMD_scriptnames:
|
||||
return set_context_in_scriptnames_cmd(xp, arg);
|
||||
|
||||
case CMD_filetype:
|
||||
return set_context_in_filetype_cmd(xp, arg);
|
||||
|
||||
case CMD_lua:
|
||||
case CMD_equal:
|
||||
xp->xp_context = EXPAND_LUA;
|
||||
@ -2565,6 +2623,30 @@ static int expand_files_and_dirs(expand_T *xp, char *pat, char ***matches, int *
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// Function given to ExpandGeneric() to obtain the possible arguments of the
|
||||
/// ":filetype {plugin,indent}" command.
|
||||
static char *get_filetypecmd_arg(expand_T *xp FUNC_ATTR_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 opts_all[idx];
|
||||
}
|
||||
if (filetype_expand_what == EXP_FILETYPECMD_PLUGIN && idx < 3) {
|
||||
return opts_plugin[idx];
|
||||
}
|
||||
if (filetype_expand_what == EXP_FILETYPECMD_INDENT && idx < 3) {
|
||||
return opts_indent[idx];
|
||||
}
|
||||
if (filetype_expand_what == EXP_FILETYPECMD_ONOFF && idx < 2) {
|
||||
return opts_onoff[idx];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/// Function given to ExpandGeneric() to obtain the possible arguments of the
|
||||
/// ":breakadd {expr, file, func, here}" command.
|
||||
/// ":breakdel {func, file, here}" command.
|
||||
@ -2660,6 +2742,7 @@ static int ExpandOther(char *pat, expand_T *xp, regmatch_T *rmp, char ***matches
|
||||
int escaped;
|
||||
} tab[] = {
|
||||
{ EXPAND_COMMANDS, get_command_name, false, 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 },
|
||||
@ -3643,6 +3726,9 @@ void f_getcompletion(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
set_context_for_wildcard_arg(NULL, xpc.xp_pattern, false, &xpc, &context);
|
||||
xpc.xp_pattern_len = strlen(xpc.xp_pattern);
|
||||
}
|
||||
if (xpc.xp_context == EXPAND_FILETYPECMD) {
|
||||
filetype_expand_what = EXP_FILETYPECMD_ALL;
|
||||
}
|
||||
|
||||
theend:
|
||||
if (xpc.xp_context == EXPAND_LUA) {
|
||||
|
@ -108,6 +108,7 @@ enum {
|
||||
EXPAND_DIRS_IN_CDPATH,
|
||||
EXPAND_SHELLCMDLINE,
|
||||
EXPAND_FINDFUNC,
|
||||
EXPAND_FILETYPECMD,
|
||||
EXPAND_CHECKHEALTH,
|
||||
EXPAND_LUA,
|
||||
};
|
||||
|
@ -3831,6 +3831,7 @@ M.funcs = {
|
||||
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
|
||||
|
@ -72,6 +72,7 @@ static const char *command_complete[] = {
|
||||
[EXPAND_FILES] = "file",
|
||||
[EXPAND_FILES_IN_PATH] = "file_in_path",
|
||||
[EXPAND_FILETYPE] = "filetype",
|
||||
[EXPAND_FILETYPECMD] = "filetypecmd",
|
||||
[EXPAND_FUNCTIONS] = "function",
|
||||
[EXPAND_HELP] = "help",
|
||||
[EXPAND_HIGHLIGHT] = "highlight",
|
||||
|
@ -548,6 +548,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')
|
||||
@ -3240,6 +3247,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
|
||||
|
Reference in New Issue
Block a user