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 <zeertzjq@outlook.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
@ -4270,6 +4270,7 @@ getcompletion({pat}, {type} [, {filtered}]) *getcompletion()*
|
|||||||
file file and directory names
|
file file and directory names
|
||||||
file_in_path file and directory names in |'path'|
|
file_in_path file and directory names in |'path'|
|
||||||
filetype filetype names |'filetype'|
|
filetype filetype names |'filetype'|
|
||||||
|
filetypecmd |:filetype| suboptions
|
||||||
function function name
|
function function name
|
||||||
help help subjects
|
help help subjects
|
||||||
highlight highlight groups
|
highlight highlight groups
|
||||||
|
|||||||
@ -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
|
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||||
@ -41624,6 +41624,8 @@ Completion: ~
|
|||||||
"o" - complete using 'omnifunc'
|
"o" - complete using 'omnifunc'
|
||||||
- allow to limit matches for the 'complete' sources by using the
|
- allow to limit matches for the 'complete' sources by using the
|
||||||
"{flag}^<limit>" notation
|
"{flag}^<limit>" notation
|
||||||
|
- add ":filetype" command completion
|
||||||
|
- add "filetypecmd" completion type for |getcompletion()|
|
||||||
|
|
||||||
Options: ~
|
Options: ~
|
||||||
- the default for 'commentstring' contains whitespace padding to have
|
- the default for 'commentstring' contains whitespace padding to have
|
||||||
|
|||||||
@ -53,6 +53,7 @@ cmdline_fuzzy_completion_supported(expand_T *xp)
|
|||||||
&& xp->xp_context != EXPAND_FILES
|
&& xp->xp_context != EXPAND_FILES
|
||||||
&& xp->xp_context != EXPAND_FILES_IN_PATH
|
&& xp->xp_context != EXPAND_FILES_IN_PATH
|
||||||
&& xp->xp_context != EXPAND_FILETYPE
|
&& xp->xp_context != EXPAND_FILETYPE
|
||||||
|
&& xp->xp_context != EXPAND_FILETYPECMD
|
||||||
&& xp->xp_context != EXPAND_FINDFUNC
|
&& xp->xp_context != EXPAND_FINDFUNC
|
||||||
&& xp->xp_context != EXPAND_HELP
|
&& xp->xp_context != EXPAND_HELP
|
||||||
&& xp->xp_context != EXPAND_KEYMAP
|
&& xp->xp_context != EXPAND_KEYMAP
|
||||||
@ -2058,6 +2059,18 @@ set_context_in_lang_cmd(expand_T *xp, char_u *arg)
|
|||||||
}
|
}
|
||||||
#endif
|
#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
|
#ifdef FEAT_EVAL
|
||||||
static enum
|
static enum
|
||||||
{
|
{
|
||||||
@ -2143,6 +2156,53 @@ set_context_in_scriptnames_cmd(expand_T *xp, char_u *arg)
|
|||||||
}
|
}
|
||||||
#endif
|
#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'.
|
* 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'.
|
* The argument to the command is 'arg' and the argument flags is 'argt'.
|
||||||
@ -2515,6 +2575,8 @@ set_context_by_cmdname(
|
|||||||
case CMD_scriptnames:
|
case CMD_scriptnames:
|
||||||
return set_context_in_scriptnames_cmd(xp, arg);
|
return set_context_in_scriptnames_cmd(xp, arg);
|
||||||
#endif
|
#endif
|
||||||
|
case CMD_filetype:
|
||||||
|
return set_context_in_filetype_cmd(xp, arg);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -2949,6 +3011,29 @@ get_behave_arg(expand_T *xp UNUSED, int idx)
|
|||||||
return NULL;
|
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
|
#ifdef FEAT_EVAL
|
||||||
/*
|
/*
|
||||||
* Function given to ExpandGeneric() to obtain the possible arguments of the
|
* Function given to ExpandGeneric() to obtain the possible arguments of the
|
||||||
@ -3040,6 +3125,7 @@ ExpandOther(
|
|||||||
{
|
{
|
||||||
{EXPAND_COMMANDS, get_command_name, FALSE, TRUE},
|
{EXPAND_COMMANDS, get_command_name, FALSE, TRUE},
|
||||||
{EXPAND_BEHAVE, get_behave_arg, TRUE, TRUE},
|
{EXPAND_BEHAVE, get_behave_arg, TRUE, TRUE},
|
||||||
|
{EXPAND_FILETYPECMD, get_filetypecmd_arg, TRUE, TRUE},
|
||||||
{EXPAND_MAPCLEAR, get_mapclear_arg, TRUE, TRUE},
|
{EXPAND_MAPCLEAR, get_mapclear_arg, TRUE, TRUE},
|
||||||
{EXPAND_MESSAGES, get_messages_arg, TRUE, TRUE},
|
{EXPAND_MESSAGES, get_messages_arg, TRUE, TRUE},
|
||||||
{EXPAND_HISTORY, get_history_arg, TRUE, TRUE},
|
{EXPAND_HISTORY, get_history_arg, TRUE, TRUE},
|
||||||
@ -4295,6 +4381,8 @@ f_getcompletion(typval_T *argvars, typval_T *rettv)
|
|||||||
&context);
|
&context);
|
||||||
xpc.xp_pattern_len = (int)STRLEN(xpc.xp_pattern);
|
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))
|
if (cmdline_fuzzy_completion_supported(&xpc))
|
||||||
|
|||||||
@ -684,6 +684,13 @@ func Test_getcompletion()
|
|||||||
let l = getcompletion('kill', 'expression')
|
let l = getcompletion('kill', 'expression')
|
||||||
call assert_equal([], l)
|
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')
|
let l = getcompletion('tag', 'function')
|
||||||
call assert_true(index(l, 'taglist(') >= 0)
|
call assert_true(index(l, 'taglist(') >= 0)
|
||||||
let l = getcompletion('paint', 'function')
|
let l = getcompletion('paint', 'function')
|
||||||
@ -3209,6 +3216,26 @@ func Test_fuzzy_completion_behave()
|
|||||||
set wildoptions&
|
set wildoptions&
|
||||||
endfunc
|
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
|
" " colorscheme name fuzzy completion - NOT supported
|
||||||
" func Test_fuzzy_completion_colorscheme()
|
" func Test_fuzzy_completion_colorscheme()
|
||||||
" endfunc
|
" endfunc
|
||||||
|
|||||||
@ -71,6 +71,7 @@ static keyvalue_T command_complete_tab[] =
|
|||||||
KEYVALUE_ENTRY(EXPAND_FILES, "file"),
|
KEYVALUE_ENTRY(EXPAND_FILES, "file"),
|
||||||
KEYVALUE_ENTRY(EXPAND_FILES_IN_PATH, "file_in_path"),
|
KEYVALUE_ENTRY(EXPAND_FILES_IN_PATH, "file_in_path"),
|
||||||
KEYVALUE_ENTRY(EXPAND_FILETYPE, "filetype"),
|
KEYVALUE_ENTRY(EXPAND_FILETYPE, "filetype"),
|
||||||
|
KEYVALUE_ENTRY(EXPAND_FILETYPECMD, "filetypecmd"),
|
||||||
KEYVALUE_ENTRY(EXPAND_FUNCTIONS, "function"),
|
KEYVALUE_ENTRY(EXPAND_FUNCTIONS, "function"),
|
||||||
KEYVALUE_ENTRY(EXPAND_HELP, "help"),
|
KEYVALUE_ENTRY(EXPAND_HELP, "help"),
|
||||||
KEYVALUE_ENTRY(EXPAND_HIGHLIGHT, "highlight"),
|
KEYVALUE_ENTRY(EXPAND_HIGHLIGHT, "highlight"),
|
||||||
|
|||||||
@ -704,6 +704,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1340,
|
||||||
/**/
|
/**/
|
||||||
1339,
|
1339,
|
||||||
/**/
|
/**/
|
||||||
|
|||||||
@ -854,6 +854,7 @@ extern int (*dyn_libintl_wputenv)(const wchar_t *envstring);
|
|||||||
#define EXPAND_SHELLCMDLINE 60
|
#define EXPAND_SHELLCMDLINE 60
|
||||||
#define EXPAND_FINDFUNC 61
|
#define EXPAND_FINDFUNC 61
|
||||||
#define EXPAND_HIGHLIGHT_GROUP 62
|
#define EXPAND_HIGHLIGHT_GROUP 62
|
||||||
|
#define EXPAND_FILETYPECMD 63
|
||||||
|
|
||||||
|
|
||||||
// Values for exmode_active (0 is no exmode)
|
// Values for exmode_active (0 is no exmode)
|
||||||
|
|||||||
Reference in New Issue
Block a user