patch 9.1.1138: cmdline completion for :hi is too simplistic
Problem: Existing cmdline completion for :highlight was barebone and
only completed the highlight group names.
Solution: Implement full completion for the highlight group arguments
such as guifg and cterm. If the user tries to complete
immediately after the '=' (e.g. `hi Normal guifg=<Tab>`), the
completion will fill in the existing value, similar to how
cmdline completion for options work (Yee Cheng Chin).
closes: #16712
Signed-off-by: Yee Cheng Chin <ychin.git@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
committed by
Christian Brabandt
parent
f4b36417e8
commit
a7b8120820
@ -1,4 +1,4 @@
|
|||||||
*eval.txt* For Vim version 9.1. Last change: 2025 Jan 29
|
*eval.txt* For Vim version 9.1. Last change: 2025 Feb 23
|
||||||
|
|
||||||
|
|
||||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||||
@ -2081,7 +2081,7 @@ v:colornames A dictionary that maps color names to hex color strings. These
|
|||||||
|
|
||||||
You can make changes to that file, but make sure to add new
|
You can make changes to that file, but make sure to add new
|
||||||
keys instead of updating existing ones, otherwise Vim will skip
|
keys instead of updating existing ones, otherwise Vim will skip
|
||||||
loading the file (thinking is hasn't been changed).
|
loading the file (thinking it hasn't been changed).
|
||||||
|
|
||||||
*v:completed_item* *completed_item-variable*
|
*v:completed_item* *completed_item-variable*
|
||||||
v:completed_item
|
v:completed_item
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
*syntax.txt* For Vim version 9.1. Last change: 2025 Feb 20
|
*syntax.txt* For Vim version 9.1. Last change: 2025 Feb 23
|
||||||
|
|
||||||
|
|
||||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||||
@ -5432,6 +5432,10 @@ in their own color.
|
|||||||
See |:highlight-default| for the optional [default]
|
See |:highlight-default| for the optional [default]
|
||||||
argument.
|
argument.
|
||||||
|
|
||||||
|
:hi[ghlight][!] [default] link {from-group} {to-group}
|
||||||
|
:hi[ghlight][!] [default] link {from-group} NONE
|
||||||
|
See |:hi-link|.
|
||||||
|
|
||||||
Normally a highlight group is added once when starting up. This sets the
|
Normally a highlight group is added once when starting up. This sets the
|
||||||
default values for the highlighting. After that, you can use additional
|
default values for the highlighting. After that, you can use additional
|
||||||
highlight commands to change the arguments that you want to set to non-default
|
highlight commands to change the arguments that you want to set to non-default
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
*version9.txt* For Vim version 9.1. Last change: 2025 Feb 11
|
*version9.txt* For Vim version 9.1. Last change: 2025 Feb 23
|
||||||
|
|
||||||
|
|
||||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||||
@ -41573,8 +41573,11 @@ Include the "linematch" algorithm for the 'diffopt' setting. This aligns
|
|||||||
changes between buffers on similar lines improving the diff highlighting in
|
changes between buffers on similar lines improving the diff highlighting in
|
||||||
Vim
|
Vim
|
||||||
|
|
||||||
Adjusted default values ~
|
*changed-9.2*
|
||||||
-----------------------
|
Changed~
|
||||||
|
-------
|
||||||
|
|
||||||
|
Default values: ~
|
||||||
- the default 'history' option value has been increased to 200 and removed
|
- the default 'history' option value has been increased to 200 and removed
|
||||||
from |defaults.vim|
|
from |defaults.vim|
|
||||||
- the default 'backspace' option for Vim has been set to "indent,eol,start"
|
- the default 'backspace' option for Vim has been set to "indent,eol,start"
|
||||||
@ -41584,61 +41587,69 @@ Adjusted default values ~
|
|||||||
- the default value of the 'keyprotocol' option has been updated and support
|
- the default value of the 'keyprotocol' option has been updated and support
|
||||||
for the ghostty terminal emulator (using kitty protocol) has been added
|
for the ghostty terminal emulator (using kitty protocol) has been added
|
||||||
|
|
||||||
*changed-9.2*
|
|
||||||
Changed~
|
Completion: ~
|
||||||
-------
|
|
||||||
- use 'smoothscroll' logic for CTRL-F and CTRL-B for pagewise scrolling
|
|
||||||
- use 'smoothscroll' logic for CTRL-D and CTRL-U for half-pagewise scrolling
|
|
||||||
- the default for 'commentstring' contains whitespace padding to have
|
|
||||||
automatic comments look nicer |comment-install|
|
|
||||||
- 'completeopt' is now a |global-local| option.
|
|
||||||
- 'nrformats' accepts the new "blank" suboption, to determine a signed or
|
|
||||||
unsigned number based on whitespace in front of a minus sign.
|
|
||||||
- allow to specify a priority when defining a new sign |:sign-define|
|
|
||||||
- provide information about function arguments using the get(func, "arity")
|
|
||||||
function |get()-func|
|
|
||||||
- |:bwipe| also wipes jumplist and tagstack data
|
|
||||||
- moving in the buffer list using |:bnext| and similar commands, behaves as
|
|
||||||
documented and skips help buffers (if not run from a help buffer, else
|
|
||||||
moves to the next/previous help buffer).
|
|
||||||
- allow to complete directories from 'cdpath' for |:cd| and similar commands,
|
- allow to complete directories from 'cdpath' for |:cd| and similar commands,
|
||||||
add the "cd_in_path" completion type for e.g. |:command-complete| and
|
add the "cd_in_path" completion type for e.g. |:command-complete| and
|
||||||
|getcompletion()|
|
|getcompletion()|
|
||||||
- allow to complete shell commands and files using the new shellcmdline
|
- allow to complete shell commands and files using the new shellcmdline
|
||||||
completion type using |:command-complete| and |getcmdcomplpat()|
|
completion type using |:command-complete| and |getcmdcomplpat()|
|
||||||
- add 'cpoptions' flag "z" |cpo-z|, to disable some (traditional) vi
|
|
||||||
behaviour/inconsistency (see |d-special| and |cw|).
|
|
||||||
- allow to specify additional attributes in the completion menu (allows to
|
- allow to specify additional attributes in the completion menu (allows to
|
||||||
mark deprecated attributes from LSP server) |complete-items|
|
mark deprecated attributes from LSP server) |complete-items|
|
||||||
- the regex engines match correctly case-insensitive multi-byte characters
|
- the completed word and completion type are provided when handling the
|
||||||
(and apply proper case folding)
|
|CompleteDone| autocommand in the |v:event| dictionary
|
||||||
|
- |complete_info()| returns the list of matches shown in the poppu menu via
|
||||||
|
the "matches" key
|
||||||
|
- New option value for 'completeopt':
|
||||||
|
"nosort" - do not sort completion results
|
||||||
|
"preinsert" - highlight to be inserted values
|
||||||
|
- handle multi-line completion as expected
|
||||||
|
- improved commandline completion for the |:hi| command
|
||||||
|
|
||||||
|
Options: ~
|
||||||
|
- the default for 'commentstring' contains whitespace padding to have
|
||||||
|
automatic comments look nicer |comment-install|
|
||||||
|
- 'completeopt' is now a |global-local| option.
|
||||||
|
- 'nrformats' accepts the new "blank" suboption, to determine a signed or
|
||||||
|
unsigned number based on whitespace in front of a minus sign.
|
||||||
|
- add 'cpoptions' flag "z" |cpo-z|, to disable some (traditional) vi
|
||||||
|
behaviour/inconsistency (see |d-special| and |cw|).
|
||||||
|
- 'rulerformat' now supports the |stl-%!| item
|
||||||
|
- use 'smoothscroll' logic for CTRL-F / CTRL-B for pagewise scrolling
|
||||||
|
and CTRL-D / CTRL-U for half-pagewise scrolling
|
||||||
|
|
||||||
|
Ex commands: ~
|
||||||
|
- allow to specify a priority when defining a new sign |:sign-define|
|
||||||
|
- |:bwipe| also wipes jumplist and tagstack data
|
||||||
|
- moving in the buffer list using |:bnext| and similar commands, behaves as
|
||||||
|
documented and skips help buffers (if not run from a help buffer, else
|
||||||
|
moves to the next/previous help buffer).
|
||||||
- |:keeppatterns| preserves the last substitute pattern when used with |:s|
|
- |:keeppatterns| preserves the last substitute pattern when used with |:s|
|
||||||
|
|
||||||
|
Functions: ~
|
||||||
|
- provide information about function arguments using the get(func, "arity")
|
||||||
|
function |get()-func|
|
||||||
- |setqflist()| and |setloclist()| can optionally try to preserve the current
|
- |setqflist()| and |setloclist()| can optionally try to preserve the current
|
||||||
selection in the quickfix list with the "u" action.
|
selection in the quickfix list with the "u" action.
|
||||||
|
- allow to pass local Vim script variables to python interpreter |py3eval()|
|
||||||
|
- |getwininfo()| now also returns the "leftcol" property for a window
|
||||||
|
- |v:stacktrace| The stack trace of the exception most recently caught and
|
||||||
|
not finished
|
||||||
|
- Add the optional {opts} |Dict| argument to |getchar()| to control: cursor
|
||||||
|
behaviour, return type and whether or not to simplify the returned key
|
||||||
|
|
||||||
|
Others: ~
|
||||||
|
- the regex engines match correctly case-insensitive multi-byte characters
|
||||||
|
(and apply proper case folding)
|
||||||
- the putty terminal is detected using an |TermResponse| autocommand in
|
- the putty terminal is detected using an |TermResponse| autocommand in
|
||||||
|defaults.vim| and Vim switches to a dark background
|
|defaults.vim| and Vim switches to a dark background
|
||||||
- the |help-TOC| package is included to ease navigating the documentation.
|
- the |help-TOC| package is included to ease navigating the documentation.
|
||||||
- an interactive tutor plugin has been included |vim-tutor-mode|, can be
|
- an interactive tutor plugin has been included |vim-tutor-mode|, can be
|
||||||
started via |:Tutor|
|
started via |:Tutor|
|
||||||
- improve the |vimtutor| and add a second chapter for more advanced tips
|
- improve the |vimtutor| and add a second chapter for more advanced tips
|
||||||
- allow to pass local Vim script variables to python interpreter |py3eval()|
|
|
||||||
- |getwininfo()| now also returns the "leftcol" property for a window
|
|
||||||
- 'rulerformat' now supports the |stl-%!| item
|
|
||||||
- the completed word and completion type are provided when handling the
|
|
||||||
|CompleteDone| autocommand in the |v:event| dictionary
|
|
||||||
- |complete_info()| returns the list of matches shown in the poppu menu via
|
|
||||||
the "matches" key
|
|
||||||
- |v:stacktrace| The stack trace of the exception most recently caught and
|
|
||||||
not finished
|
|
||||||
- New option value for 'completeopt':
|
|
||||||
"nosort" - do not sort completion results
|
|
||||||
"preinsert" - highlight to be inserted values
|
|
||||||
- add |dist#vim9#Launch()| and |dist#vim9#Open()| to the |vim-script-library|
|
- add |dist#vim9#Launch()| and |dist#vim9#Open()| to the |vim-script-library|
|
||||||
and decouple it from |netrw|
|
and decouple it from |netrw|
|
||||||
- new digraph "APPROACHES THE LIMIT" using ".="
|
- new digraph "APPROACHES THE LIMIT" using ".="
|
||||||
- Add the optional {opts} |Dict| argument to |getchar()| to control: cursor
|
|
||||||
behaviour, return type and whether or not to simplify the returned key
|
|
||||||
- handle multi-line completion as expected
|
|
||||||
|
|
||||||
*added-9.2*
|
*added-9.2*
|
||||||
Added ~
|
Added ~
|
||||||
|
|||||||
@ -3221,6 +3221,8 @@ ExpandFromContext(
|
|||||||
ret = ExpandMappings(pat, ®match, numMatches, matches);
|
ret = ExpandMappings(pat, ®match, numMatches, matches);
|
||||||
else if (xp->xp_context == EXPAND_ARGOPT)
|
else if (xp->xp_context == EXPAND_ARGOPT)
|
||||||
ret = expand_argopt(pat, xp, ®match, matches, numMatches);
|
ret = expand_argopt(pat, xp, ®match, matches, numMatches);
|
||||||
|
else if (xp->xp_context == EXPAND_HIGHLIGHT_GROUP)
|
||||||
|
ret = expand_highlight_group(pat, xp, ®match, matches, numMatches);
|
||||||
#if defined(FEAT_TERMINAL)
|
#if defined(FEAT_TERMINAL)
|
||||||
else if (xp->xp_context == EXPAND_TERMINALOPT)
|
else if (xp->xp_context == EXPAND_TERMINALOPT)
|
||||||
ret = expand_terminal_opt(pat, xp, ®match, matches, numMatches);
|
ret = expand_terminal_opt(pat, xp, ®match, matches, numMatches);
|
||||||
@ -3239,18 +3241,6 @@ ExpandFromContext(
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Expand a list of names.
|
|
||||||
*
|
|
||||||
* Generic function for command line completion. It calls a function to
|
|
||||||
* obtain strings, one by one. The strings are matched against a regexp
|
|
||||||
* program. Matching strings are copied into an array, which is returned.
|
|
||||||
*
|
|
||||||
* If 'fuzzy' is TRUE, then fuzzy matching is used. Otherwise, regex matching
|
|
||||||
* is used.
|
|
||||||
*
|
|
||||||
* Returns OK when no problems encountered, FAIL for error (out of memory).
|
|
||||||
*/
|
|
||||||
int
|
int
|
||||||
ExpandGeneric(
|
ExpandGeneric(
|
||||||
char_u *pat,
|
char_u *pat,
|
||||||
@ -3261,6 +3251,38 @@ ExpandGeneric(
|
|||||||
char_u *((*func)(expand_T *, int)),
|
char_u *((*func)(expand_T *, int)),
|
||||||
// returns a string from the list
|
// returns a string from the list
|
||||||
int escaped)
|
int escaped)
|
||||||
|
{
|
||||||
|
return ExpandGenericExt(
|
||||||
|
pat, xp, regmatch, matches, numMatches, func, escaped, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Expand a list of names.
|
||||||
|
*
|
||||||
|
* Generic function for command line completion. It calls a function to
|
||||||
|
* obtain strings, one by one. The strings are matched against a regexp
|
||||||
|
* program. Matching strings are copied into an array, which is returned.
|
||||||
|
*
|
||||||
|
* If 'fuzzy' is TRUE, then fuzzy matching is used. Otherwise, regex matching
|
||||||
|
* is used.
|
||||||
|
*
|
||||||
|
* 'sortStartIdx' allows the caller to control sorting behavior. Items before
|
||||||
|
* the index will not be sorted. Pass 0 to sort all, and -1 to prevent any
|
||||||
|
* sorting.
|
||||||
|
*
|
||||||
|
* Returns OK when no problems encountered, FAIL for error (out of memory).
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
ExpandGenericExt(
|
||||||
|
char_u *pat,
|
||||||
|
expand_T *xp,
|
||||||
|
regmatch_T *regmatch,
|
||||||
|
char_u ***matches,
|
||||||
|
int *numMatches,
|
||||||
|
char_u *((*func)(expand_T *, int)),
|
||||||
|
// returns a string from the list
|
||||||
|
int escaped,
|
||||||
|
int sortStartIdx)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
garray_T ga;
|
garray_T ga;
|
||||||
@ -3271,6 +3293,7 @@ ExpandGeneric(
|
|||||||
int match;
|
int match;
|
||||||
int sort_matches = FALSE;
|
int sort_matches = FALSE;
|
||||||
int funcsort = FALSE;
|
int funcsort = FALSE;
|
||||||
|
int sortStartMatchIdx = -1;
|
||||||
|
|
||||||
fuzzy = cmdline_fuzzy_complete(pat);
|
fuzzy = cmdline_fuzzy_complete(pat);
|
||||||
*matches = NULL;
|
*matches = NULL;
|
||||||
@ -3346,6 +3369,12 @@ ExpandGeneric(
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (sortStartIdx >= 0 && i >= sortStartIdx && sortStartMatchIdx == -1)
|
||||||
|
{
|
||||||
|
// Found first item to start sorting from. This is usually 0.
|
||||||
|
sortStartMatchIdx = ga.ga_len;
|
||||||
|
}
|
||||||
|
|
||||||
++ga.ga_len;
|
++ga.ga_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3371,14 +3400,14 @@ ExpandGeneric(
|
|||||||
funcsort = TRUE;
|
funcsort = TRUE;
|
||||||
|
|
||||||
// Sort the matches.
|
// Sort the matches.
|
||||||
if (sort_matches)
|
if (sort_matches && sortStartMatchIdx != -1)
|
||||||
{
|
{
|
||||||
if (funcsort)
|
if (funcsort)
|
||||||
// <SNR> functions should be sorted to the end.
|
// <SNR> functions should be sorted to the end.
|
||||||
qsort((void *)ga.ga_data, (size_t)ga.ga_len, sizeof(char_u *),
|
qsort((void *)ga.ga_data, (size_t)ga.ga_len, sizeof(char_u *),
|
||||||
sort_func_compare);
|
sort_func_compare);
|
||||||
else
|
else
|
||||||
sort_strings((char_u **)ga.ga_data, ga.ga_len);
|
sort_strings((char_u **)ga.ga_data + sortStartMatchIdx, ga.ga_len - sortStartMatchIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fuzzy)
|
if (!fuzzy)
|
||||||
|
|||||||
420
src/highlight.c
420
src/highlight.c
@ -1691,6 +1691,8 @@ do_highlight(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Note: Keep this in sync with get_highlight_group_key.
|
||||||
|
|
||||||
// Isolate the key ("term", "ctermfg", "ctermbg", "font", "guifg"
|
// Isolate the key ("term", "ctermfg", "ctermbg", "font", "guifg"
|
||||||
// or "guibg").
|
// or "guibg").
|
||||||
while (*linep && !VIM_ISWHITE(*linep) && *linep != '=')
|
while (*linep && !VIM_ISWHITE(*linep) && *linep != '=')
|
||||||
@ -3058,6 +3060,7 @@ highlight_list_one(int id)
|
|||||||
if (message_filtered(sgp->sg_name))
|
if (message_filtered(sgp->sg_name))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Note: Keep this in sync with expand_highlight_group().
|
||||||
didh = highlight_list_arg(id, didh, LIST_ATTR,
|
didh = highlight_list_arg(id, didh, LIST_ATTR,
|
||||||
sgp->sg_term, NULL, "term");
|
sgp->sg_term, NULL, "term");
|
||||||
didh = highlight_list_arg(id, didh, LIST_STRING,
|
didh = highlight_list_arg(id, didh, LIST_STRING,
|
||||||
@ -3108,37 +3111,24 @@ highlight_list_one(int id)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static char_u*
|
||||||
highlight_list_arg(
|
highlight_arg_to_string(
|
||||||
int id,
|
|
||||||
int didh,
|
|
||||||
int type,
|
int type,
|
||||||
int iarg,
|
int iarg,
|
||||||
char_u *sarg,
|
char_u *sarg,
|
||||||
char *name)
|
char_u *buf)
|
||||||
{
|
{
|
||||||
char_u buf[MAX_ATTR_LEN];
|
|
||||||
char_u *ts;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (got_int)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (type == LIST_STRING ? (sarg == NULL) : (iarg == 0))
|
|
||||||
return didh;
|
|
||||||
|
|
||||||
ts = buf;
|
|
||||||
if (type == LIST_INT)
|
if (type == LIST_INT)
|
||||||
sprintf((char *)buf, "%d", iarg - 1);
|
sprintf((char *)buf, "%d", iarg - 1);
|
||||||
else if (type == LIST_STRING)
|
else if (type == LIST_STRING)
|
||||||
ts = sarg;
|
return sarg;
|
||||||
else // type == LIST_ATTR
|
else // type == LIST_ATTR
|
||||||
{
|
{
|
||||||
size_t buflen;
|
size_t buflen;
|
||||||
|
|
||||||
buf[0] = NUL;
|
buf[0] = NUL;
|
||||||
buflen = 0;
|
buflen = 0;
|
||||||
for (i = 0; i < (int)ARRAY_LENGTH(highlight_index_tab); ++i)
|
for (int i = 0; i < (int)ARRAY_LENGTH(highlight_index_tab); ++i)
|
||||||
{
|
{
|
||||||
if (iarg & highlight_index_tab[i]->key)
|
if (iarg & highlight_index_tab[i]->key)
|
||||||
{
|
{
|
||||||
@ -3153,6 +3143,28 @@ highlight_list_arg(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
highlight_list_arg(
|
||||||
|
int id,
|
||||||
|
int didh,
|
||||||
|
int type,
|
||||||
|
int iarg,
|
||||||
|
char_u *sarg,
|
||||||
|
char *name)
|
||||||
|
{
|
||||||
|
char_u buf[MAX_ATTR_LEN];
|
||||||
|
char_u *ts;
|
||||||
|
|
||||||
|
if (got_int)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (type == LIST_STRING ? (sarg == NULL) : (iarg == 0))
|
||||||
|
return didh;
|
||||||
|
|
||||||
|
ts = highlight_arg_to_string(type, iarg, sarg, buf);
|
||||||
|
|
||||||
(void)syn_list_header(didh,
|
(void)syn_list_header(didh,
|
||||||
(int)(vim_strsize(ts) + STRLEN(name) + 1), id);
|
(int)(vim_strsize(ts) + STRLEN(name) + 1), id);
|
||||||
@ -4078,6 +4090,15 @@ highlight_changed(void)
|
|||||||
static void highlight_list(void);
|
static void highlight_list(void);
|
||||||
static void highlight_list_two(int cnt, int attr);
|
static void highlight_list_two(int cnt, int attr);
|
||||||
|
|
||||||
|
// context for :highlight <group> <arg> expansion
|
||||||
|
static int expand_hi_synid = 0; // ID for highlight group being completed
|
||||||
|
static int expand_hi_equal_col = 0; // column where the '=' is
|
||||||
|
static int expand_hi_include_orig = 0; // whether to fill the existing current value or not
|
||||||
|
static char_u *expand_hi_curvalue = NULL; // the existing current value
|
||||||
|
#if defined(FEAT_EVAL) && (defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS))
|
||||||
|
static dict_iterator_T expand_colornames_iter; // iterator for looping through v:colornames
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Handle command line completion for :highlight command.
|
* Handle command line completion for :highlight command.
|
||||||
*/
|
*/
|
||||||
@ -4085,10 +4106,12 @@ static void highlight_list_two(int cnt, int attr);
|
|||||||
set_context_in_highlight_cmd(expand_T *xp, char_u *arg)
|
set_context_in_highlight_cmd(expand_T *xp, char_u *arg)
|
||||||
{
|
{
|
||||||
char_u *p;
|
char_u *p;
|
||||||
|
int expand_group = TRUE;
|
||||||
|
|
||||||
// Default: expand group names
|
// Default: expand group names
|
||||||
xp->xp_context = EXPAND_HIGHLIGHT;
|
xp->xp_context = EXPAND_HIGHLIGHT;
|
||||||
xp->xp_pattern = arg;
|
xp->xp_pattern = arg;
|
||||||
|
include_none = 0;
|
||||||
include_link = 2;
|
include_link = 2;
|
||||||
include_default = 1;
|
include_default = 1;
|
||||||
|
|
||||||
@ -4114,9 +4137,11 @@ set_context_in_highlight_cmd(expand_T *xp, char_u *arg)
|
|||||||
// past group name
|
// past group name
|
||||||
include_link = 0;
|
include_link = 0;
|
||||||
if (arg[1] == 'i' && arg[0] == 'N')
|
if (arg[1] == 'i' && arg[0] == 'N')
|
||||||
|
{
|
||||||
highlight_list();
|
highlight_list();
|
||||||
if (STRNCMP("link", arg, p - arg) == 0
|
expand_group = FALSE;
|
||||||
|| STRNCMP("clear", arg, p - arg) == 0)
|
}
|
||||||
|
if (STRNCMP("link", arg, p - arg) == 0)
|
||||||
{
|
{
|
||||||
xp->xp_pattern = skipwhite(p);
|
xp->xp_pattern = skipwhite(p);
|
||||||
p = skiptowhite(xp->xp_pattern);
|
p = skiptowhite(xp->xp_pattern);
|
||||||
@ -4124,10 +4149,67 @@ set_context_in_highlight_cmd(expand_T *xp, char_u *arg)
|
|||||||
{
|
{
|
||||||
xp->xp_pattern = skipwhite(p);
|
xp->xp_pattern = skipwhite(p);
|
||||||
p = skiptowhite(xp->xp_pattern);
|
p = skiptowhite(xp->xp_pattern);
|
||||||
|
include_none = 1;
|
||||||
}
|
}
|
||||||
|
expand_group = FALSE;
|
||||||
|
}
|
||||||
|
else if (STRNCMP("clear", arg, p - arg) == 0)
|
||||||
|
{
|
||||||
|
xp->xp_pattern = skipwhite(p);
|
||||||
|
p = skiptowhite(xp->xp_pattern);
|
||||||
|
expand_group = FALSE;
|
||||||
}
|
}
|
||||||
if (*p != NUL) // past group name(s)
|
if (*p != NUL) // past group name(s)
|
||||||
xp->xp_context = EXPAND_NOTHING;
|
{
|
||||||
|
if (expand_group)
|
||||||
|
{
|
||||||
|
// expansion will be done in expand_highlight_group()
|
||||||
|
xp->xp_context = EXPAND_HIGHLIGHT_GROUP;
|
||||||
|
|
||||||
|
expand_hi_synid = syn_namen2id(arg, (int)(p - arg));
|
||||||
|
|
||||||
|
while (*p != NUL)
|
||||||
|
{
|
||||||
|
arg = skipwhite(p);
|
||||||
|
p = skiptowhite(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
p = vim_strchr(arg, '=');
|
||||||
|
if (p == NULL)
|
||||||
|
{
|
||||||
|
// Didn't find a key=<value> pattern
|
||||||
|
xp->xp_pattern = arg;
|
||||||
|
expand_hi_equal_col = -1;
|
||||||
|
expand_hi_include_orig = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Found key=<value> pattern, record the exact location
|
||||||
|
expand_hi_equal_col = (int)(p - xp->xp_line);
|
||||||
|
|
||||||
|
// Only include the original value if the pattern is empty
|
||||||
|
if (*(p + 1) == NUL)
|
||||||
|
expand_hi_include_orig = TRUE;
|
||||||
|
else
|
||||||
|
expand_hi_include_orig = FALSE;
|
||||||
|
|
||||||
|
// Account for comma-separated values
|
||||||
|
if (STRNCMP(arg, "term=", 5) == 0 ||
|
||||||
|
STRNCMP(arg, "cterm=", 6) == 0 ||
|
||||||
|
STRNCMP(arg, "gui=", 4) == 0)
|
||||||
|
{
|
||||||
|
char_u *comma = vim_strrchr(p + 1, ',');
|
||||||
|
if (comma != NULL)
|
||||||
|
p = comma;
|
||||||
|
}
|
||||||
|
xp->xp_pattern = p + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xp->xp_context = EXPAND_NOTHING;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -4178,7 +4260,7 @@ get_highlight_name_ext(expand_T *xp UNUSED, int idx, int skip_cleared)
|
|||||||
return (char_u *)"";
|
return (char_u *)"";
|
||||||
|
|
||||||
if (idx == highlight_ga.ga_len && include_none != 0)
|
if (idx == highlight_ga.ga_len && include_none != 0)
|
||||||
return (char_u *)"none";
|
return (char_u *)"NONE";
|
||||||
if (idx == highlight_ga.ga_len + include_none && include_default != 0)
|
if (idx == highlight_ga.ga_len + include_none && include_default != 0)
|
||||||
return (char_u *)"default";
|
return (char_u *)"default";
|
||||||
if (idx == highlight_ga.ga_len + include_none + include_default
|
if (idx == highlight_ga.ga_len + include_none + include_default
|
||||||
@ -4192,6 +4274,300 @@ get_highlight_name_ext(expand_T *xp UNUSED, int idx, int skip_cleared)
|
|||||||
return HL_TABLE()[idx].sg_name;
|
return HL_TABLE()[idx].sg_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char_u *
|
||||||
|
get_highlight_attr_name(expand_T *xp UNUSED, int idx)
|
||||||
|
{
|
||||||
|
if (idx == 0)
|
||||||
|
{
|
||||||
|
// Fill with current value first
|
||||||
|
if (expand_hi_curvalue != NULL)
|
||||||
|
return expand_hi_curvalue;
|
||||||
|
else
|
||||||
|
return (char_u*)"";
|
||||||
|
}
|
||||||
|
if (idx < (int)ARRAY_LENGTH(highlight_index_tab) + 1)
|
||||||
|
{
|
||||||
|
char_u *value = highlight_index_tab[idx-1]->value.string;
|
||||||
|
if (expand_hi_curvalue != NULL && STRCMP(expand_hi_curvalue, value) == 0)
|
||||||
|
{
|
||||||
|
// Already returned the current value above, just skip.
|
||||||
|
return (char_u*)"";
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char_u *
|
||||||
|
get_highlight_cterm_color(expand_T *xp UNUSED, int idx)
|
||||||
|
{
|
||||||
|
if (idx == 0)
|
||||||
|
{
|
||||||
|
// Fill with current value first
|
||||||
|
if (expand_hi_curvalue != NULL)
|
||||||
|
return expand_hi_curvalue;
|
||||||
|
else
|
||||||
|
return (char_u*)"";
|
||||||
|
}
|
||||||
|
// See highlight_set_cterm_color()
|
||||||
|
else if (idx == 1)
|
||||||
|
return (char_u*)"fg";
|
||||||
|
else if (idx == 2)
|
||||||
|
return (char_u*)"bg";
|
||||||
|
if (idx < (int)ARRAY_LENGTH(color_name_tab) + 3)
|
||||||
|
{
|
||||||
|
char_u *value = color_name_tab[idx-3].value.string;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(FEAT_EVAL) && (defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS))
|
||||||
|
static char_u *
|
||||||
|
get_highlight_gui_color(expand_T *xp UNUSED, int idx)
|
||||||
|
{
|
||||||
|
if (idx == 0)
|
||||||
|
{
|
||||||
|
// Fill with current value first
|
||||||
|
if (expand_hi_curvalue != NULL)
|
||||||
|
return expand_hi_curvalue;
|
||||||
|
else
|
||||||
|
return (char_u*)"";
|
||||||
|
}
|
||||||
|
// See color_name2handle()
|
||||||
|
else if (idx == 1)
|
||||||
|
return (char_u*)"fg";
|
||||||
|
else if (idx == 2)
|
||||||
|
return (char_u*)"bg";
|
||||||
|
else if (idx == 3)
|
||||||
|
return (char_u*)"NONE";
|
||||||
|
|
||||||
|
// Complete from v:colornames. Don't do platform specific names for now.
|
||||||
|
typval_T *tv_result;
|
||||||
|
char_u *colorname = dict_iterate_next(&expand_colornames_iter, &tv_result);
|
||||||
|
if (colorname != NULL)
|
||||||
|
{
|
||||||
|
// :hi command doesn't allow space, so don't suggest any malformed items
|
||||||
|
if (vim_strchr(colorname, ' ') != NULL)
|
||||||
|
return (char_u*)"";
|
||||||
|
|
||||||
|
if (expand_hi_curvalue != NULL && STRICMP(expand_hi_curvalue, colorname) == 0)
|
||||||
|
{
|
||||||
|
// Already returned the current value above, just skip.
|
||||||
|
return (char_u*)"";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return colorname;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static char_u *
|
||||||
|
get_highlight_group_key(expand_T *xp UNUSED, int idx)
|
||||||
|
{
|
||||||
|
// Note: Keep this in sync with do_highlight.
|
||||||
|
static char *(p_hi_group_key_values[]) =
|
||||||
|
{
|
||||||
|
"term=",
|
||||||
|
"start=",
|
||||||
|
"stop=",
|
||||||
|
"cterm=",
|
||||||
|
"ctermfg=",
|
||||||
|
"ctermbg=",
|
||||||
|
"ctermul=",
|
||||||
|
"ctermfont=",
|
||||||
|
#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
|
||||||
|
"gui=",
|
||||||
|
"guifg=",
|
||||||
|
"guibg=",
|
||||||
|
"guisp=",
|
||||||
|
#endif
|
||||||
|
#ifdef FEAT_GUI
|
||||||
|
"font=",
|
||||||
|
#endif
|
||||||
|
"NONE",
|
||||||
|
};
|
||||||
|
|
||||||
|
if (idx < (int)ARRAY_LENGTH(p_hi_group_key_values))
|
||||||
|
return (char_u*)p_hi_group_key_values[idx];
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Command-line expansion for :hi {group-name} <args>...
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
expand_highlight_group(
|
||||||
|
char_u *pat,
|
||||||
|
expand_T *xp,
|
||||||
|
regmatch_T *rmp,
|
||||||
|
char_u ***matches,
|
||||||
|
int *numMatches)
|
||||||
|
{
|
||||||
|
if (expand_hi_equal_col != -1)
|
||||||
|
{
|
||||||
|
// List the values. First fill in the current value, then if possible colors
|
||||||
|
// or attribute names.
|
||||||
|
char_u *(*expandfunc)(expand_T *, int) = NULL;
|
||||||
|
int type = 0;
|
||||||
|
hl_group_T *sgp = NULL;
|
||||||
|
int iarg = 0;
|
||||||
|
char_u *sarg = NULL;
|
||||||
|
|
||||||
|
int unsortedItems = -1; // don't sort by default
|
||||||
|
|
||||||
|
if (expand_hi_synid != 0)
|
||||||
|
sgp = &HL_TABLE()[expand_hi_synid - 1]; // index is ID minus one
|
||||||
|
|
||||||
|
// Note: Keep this in sync with highlight_list_one().
|
||||||
|
char_u *name_end = xp->xp_line + expand_hi_equal_col;
|
||||||
|
if (name_end - xp->xp_line >= 5
|
||||||
|
&& STRNCMP(name_end - 5, " term", 5) == 0)
|
||||||
|
{
|
||||||
|
expandfunc = get_highlight_attr_name;
|
||||||
|
if (sgp)
|
||||||
|
{
|
||||||
|
type = LIST_ATTR;
|
||||||
|
iarg = sgp->sg_term;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (name_end - xp->xp_line >= 6
|
||||||
|
&& STRNCMP(name_end - 6, " cterm", 6) == 0)
|
||||||
|
{
|
||||||
|
expandfunc = get_highlight_attr_name;
|
||||||
|
if (sgp)
|
||||||
|
{
|
||||||
|
type = LIST_ATTR;
|
||||||
|
iarg = sgp->sg_cterm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
|
||||||
|
else if (name_end - xp->xp_line >= 4
|
||||||
|
&& STRNCMP(name_end - 4, " gui", 4) == 0)
|
||||||
|
{
|
||||||
|
expandfunc = get_highlight_attr_name;
|
||||||
|
if (sgp)
|
||||||
|
{
|
||||||
|
type = LIST_ATTR;
|
||||||
|
iarg = sgp->sg_gui;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else if (name_end - xp->xp_line >= 8
|
||||||
|
&& STRNCMP(name_end - 8, " ctermfg", 8) == 0)
|
||||||
|
{
|
||||||
|
expandfunc = get_highlight_cterm_color;
|
||||||
|
if (sgp)
|
||||||
|
{
|
||||||
|
type = LIST_INT;
|
||||||
|
iarg = sgp->sg_cterm_fg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (name_end - xp->xp_line >= 8
|
||||||
|
&& STRNCMP(name_end - 8, " ctermbg", 8) == 0)
|
||||||
|
{
|
||||||
|
expandfunc = get_highlight_cterm_color;
|
||||||
|
if (sgp)
|
||||||
|
{
|
||||||
|
type = LIST_INT;
|
||||||
|
iarg = sgp->sg_cterm_bg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (name_end - xp->xp_line >= 8
|
||||||
|
&& STRNCMP(name_end - 8, " ctermul", 8) == 0)
|
||||||
|
{
|
||||||
|
expandfunc = get_highlight_cterm_color;
|
||||||
|
if (sgp)
|
||||||
|
{
|
||||||
|
type = LIST_INT;
|
||||||
|
iarg = sgp->sg_cterm_ul;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if defined(FEAT_EVAL) && (defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS))
|
||||||
|
else if (name_end - xp->xp_line >= 6
|
||||||
|
&& STRNCMP(name_end - 6, " guifg", 6) == 0)
|
||||||
|
{
|
||||||
|
expandfunc = get_highlight_gui_color;
|
||||||
|
if (sgp)
|
||||||
|
{
|
||||||
|
type = LIST_STRING;
|
||||||
|
sarg = sgp->sg_gui_fg_name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (name_end - xp->xp_line >= 6
|
||||||
|
&& STRNCMP(name_end - 6, " guibg", 6) == 0)
|
||||||
|
{
|
||||||
|
expandfunc = get_highlight_gui_color;
|
||||||
|
if (sgp)
|
||||||
|
{
|
||||||
|
type = LIST_STRING;
|
||||||
|
sarg = sgp->sg_gui_bg_name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (name_end - xp->xp_line >= 6
|
||||||
|
&& STRNCMP(name_end - 6, " guisp", 6) == 0)
|
||||||
|
{
|
||||||
|
expandfunc = get_highlight_gui_color;
|
||||||
|
if (sgp)
|
||||||
|
{
|
||||||
|
type = LIST_STRING;
|
||||||
|
sarg = sgp->sg_gui_sp_name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(FEAT_EVAL) && (defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS))
|
||||||
|
if (expandfunc == get_highlight_gui_color)
|
||||||
|
{
|
||||||
|
// Top 4 items are special, after that sort all the color names
|
||||||
|
unsortedItems = 4;
|
||||||
|
|
||||||
|
dict_T *colornames_table = get_vim_var_dict(VV_COLORNAMES);
|
||||||
|
typval_T colornames_val;
|
||||||
|
colornames_val.v_type = VAR_DICT;
|
||||||
|
colornames_val.vval.v_dict = colornames_table;
|
||||||
|
dict_iterate_start(&colornames_val, &expand_colornames_iter);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char_u buf[MAX_ATTR_LEN];
|
||||||
|
|
||||||
|
if (expand_hi_synid != 0 && type != 0 && expand_hi_include_orig)
|
||||||
|
{
|
||||||
|
// Retrieve the current value to go first in completion
|
||||||
|
expand_hi_curvalue = highlight_arg_to_string(
|
||||||
|
type, iarg, sarg, buf);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
expand_hi_curvalue = NULL;
|
||||||
|
|
||||||
|
if (expandfunc != NULL)
|
||||||
|
{
|
||||||
|
return ExpandGenericExt(
|
||||||
|
pat,
|
||||||
|
xp,
|
||||||
|
rmp,
|
||||||
|
matches,
|
||||||
|
numMatches,
|
||||||
|
expandfunc,
|
||||||
|
FALSE,
|
||||||
|
unsortedItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// List all the key names
|
||||||
|
return ExpandGenericExt(
|
||||||
|
pat,
|
||||||
|
xp,
|
||||||
|
rmp,
|
||||||
|
matches,
|
||||||
|
numMatches,
|
||||||
|
get_highlight_group_key,
|
||||||
|
FALSE,
|
||||||
|
-1);
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(FEAT_GUI) || defined(PROTO)
|
#if defined(FEAT_GUI) || defined(PROTO)
|
||||||
/*
|
/*
|
||||||
* Free all the highlight group fonts.
|
* Free all the highlight group fonts.
|
||||||
|
|||||||
@ -17,6 +17,7 @@ void set_expand_context(expand_T *xp);
|
|||||||
void set_cmd_context(expand_T *xp, char_u *str, int len, int col, int use_ccline);
|
void set_cmd_context(expand_T *xp, char_u *str, int len, int col, int use_ccline);
|
||||||
int expand_cmdline(expand_T *xp, char_u *str, int col, int *matchcount, char_u ***matches);
|
int expand_cmdline(expand_T *xp, char_u *str, int col, int *matchcount, char_u ***matches);
|
||||||
int ExpandGeneric(char_u *pat, expand_T *xp, regmatch_T *regmatch, char_u ***matches, int *numMatches, char_u *((*func)(expand_T *, int)), int escaped);
|
int ExpandGeneric(char_u *pat, expand_T *xp, regmatch_T *regmatch, char_u ***matches, int *numMatches, char_u *((*func)(expand_T *, int)), int escaped);
|
||||||
|
int ExpandGenericExt(char_u *pat, expand_T *xp, regmatch_T *regmatch, char_u ***matches, int *numMatches, char_u *((*func)(expand_T *, int)), int escaped, int sortStartIdx);
|
||||||
void globpath(char_u *path, char_u *file, garray_T *ga, int expand_options, int dirs);
|
void globpath(char_u *path, char_u *file, garray_T *ga, int expand_options, int dirs);
|
||||||
int wildmenu_translate_key(cmdline_info_T *cclp, int key, expand_T *xp, int did_wild_list);
|
int wildmenu_translate_key(cmdline_info_T *cclp, int key, expand_T *xp, int did_wild_list);
|
||||||
int wildmenu_process_key(cmdline_info_T *cclp, int key, expand_T *xp);
|
int wildmenu_process_key(cmdline_info_T *cclp, int key, expand_T *xp);
|
||||||
|
|||||||
@ -43,6 +43,7 @@ int highlight_changed(void);
|
|||||||
void set_context_in_highlight_cmd(expand_T *xp, char_u *arg);
|
void set_context_in_highlight_cmd(expand_T *xp, char_u *arg);
|
||||||
char_u *get_highlight_name(expand_T *xp, int idx);
|
char_u *get_highlight_name(expand_T *xp, int idx);
|
||||||
char_u *get_highlight_name_ext(expand_T *xp, int idx, int skip_cleared);
|
char_u *get_highlight_name_ext(expand_T *xp, int idx, int skip_cleared);
|
||||||
|
int expand_highlight_group( char_u *pat, expand_T *xp, regmatch_T *rmp, char_u ***matches, int *numMatches);
|
||||||
void free_highlight_fonts(void);
|
void free_highlight_fonts(void);
|
||||||
void f_hlget(typval_T *argvars, typval_T *rettv);
|
void f_hlget(typval_T *argvars, typval_T *rettv);
|
||||||
void f_hlset(typval_T *argvars, typval_T *rettv);
|
void f_hlset(typval_T *argvars, typval_T *rettv);
|
||||||
|
|||||||
@ -6372,7 +6372,7 @@ reset_expand_highlight(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Handle command line completion for :match and :echohl command: Add "None"
|
* Handle command line completion for :match and :echohl command: Add "NONE"
|
||||||
* as highlight group.
|
* as highlight group.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
|
|||||||
@ -418,8 +418,8 @@ func Test_match_completion()
|
|||||||
hi Aardig ctermfg=green
|
hi Aardig ctermfg=green
|
||||||
call feedkeys(":match \<Tab>\<Home>\"\<CR>", 'xt')
|
call feedkeys(":match \<Tab>\<Home>\"\<CR>", 'xt')
|
||||||
call assert_equal('"match Aardig', @:)
|
call assert_equal('"match Aardig', @:)
|
||||||
call feedkeys(":match \<S-Tab>\<Home>\"\<CR>", 'xt')
|
call feedkeys(":match NON\<Tab>\<Home>\"\<CR>", 'xt')
|
||||||
call assert_equal('"match none', @:)
|
call assert_equal('"match NONE', @:)
|
||||||
call feedkeys(":match | chist\<Tab>\<C-B>\"\<CR>", 'xt')
|
call feedkeys(":match | chist\<Tab>\<C-B>\"\<CR>", 'xt')
|
||||||
call assert_equal('"match | chistory', @:)
|
call assert_equal('"match | chistory', @:)
|
||||||
endfunc
|
endfunc
|
||||||
@ -428,20 +428,37 @@ func Test_highlight_completion()
|
|||||||
hi Aardig ctermfg=green
|
hi Aardig ctermfg=green
|
||||||
call feedkeys(":hi \<Tab>\<Home>\"\<CR>", 'xt')
|
call feedkeys(":hi \<Tab>\<Home>\"\<CR>", 'xt')
|
||||||
call assert_equal('"hi Aardig', getreg(':'))
|
call assert_equal('"hi Aardig', getreg(':'))
|
||||||
|
|
||||||
|
" hi default
|
||||||
call feedkeys(":hi default \<Tab>\<Home>\"\<CR>", 'xt')
|
call feedkeys(":hi default \<Tab>\<Home>\"\<CR>", 'xt')
|
||||||
call assert_equal('"hi default Aardig', getreg(':'))
|
call assert_equal('"hi default Aardig', getreg(':'))
|
||||||
call feedkeys(":hi clear Aa\<Tab>\<Home>\"\<CR>", 'xt')
|
|
||||||
call assert_equal('"hi clear Aardig', getreg(':'))
|
|
||||||
call feedkeys(":hi li\<S-Tab>\<Home>\"\<CR>", 'xt')
|
|
||||||
call assert_equal('"hi link', getreg(':'))
|
|
||||||
call feedkeys(":hi d\<S-Tab>\<Home>\"\<CR>", 'xt')
|
call feedkeys(":hi d\<S-Tab>\<Home>\"\<CR>", 'xt')
|
||||||
call assert_equal('"hi default', getreg(':'))
|
call assert_equal('"hi default', getreg(':'))
|
||||||
|
call feedkeys(":hi default link Aa\<Tab>\<Home>\"\<CR>", 'xt')
|
||||||
|
call assert_equal('"hi default link Aardig', getreg(':'))
|
||||||
|
|
||||||
|
" hi clear only accepts one parameter
|
||||||
call feedkeys(":hi c\<S-Tab>\<Home>\"\<CR>", 'xt')
|
call feedkeys(":hi c\<S-Tab>\<Home>\"\<CR>", 'xt')
|
||||||
call assert_equal('"hi clear', getreg(':'))
|
call assert_equal('"hi clear', getreg(':'))
|
||||||
|
call feedkeys(":hi clear Aa\<Tab>\<Home>\"\<CR>", 'xt')
|
||||||
|
call assert_equal('"hi clear Aardig', getreg(':'))
|
||||||
call feedkeys(":hi clear Aardig Aard\<Tab>\<C-B>\"\<CR>", 'xt')
|
call feedkeys(":hi clear Aardig Aard\<Tab>\<C-B>\"\<CR>", 'xt')
|
||||||
call assert_equal('"hi clear Aardig Aardig', getreg(':'))
|
call assert_equal("\"hi clear Aardig Aard\<Tab>", getreg(':'))
|
||||||
call feedkeys(":hi Aardig \<Tab>\<C-B>\"\<CR>", 'xt')
|
" hi link accepts up to two parameters
|
||||||
call assert_equal("\"hi Aardig \t", getreg(':'))
|
call feedkeys(":hi li\<S-Tab>\<Home>\"\<CR>", 'xt')
|
||||||
|
call assert_equal('"hi link', getreg(':'))
|
||||||
|
call assert_equal('"hi link', getreg(':'))
|
||||||
|
call feedkeys(":hi link Aa\<Tab>\<Home>\"\<CR>", 'xt')
|
||||||
|
call assert_equal('"hi link Aardig', getreg(':'))
|
||||||
|
call feedkeys(":hi link Aardig Aard\<Tab>\<C-B>\"\<CR>", 'xt')
|
||||||
|
call assert_equal("\"hi link Aardig Aardig", getreg(':'))
|
||||||
|
call feedkeys(":hi link Aardig Aardig Aard\<Tab>\<C-B>\"\<CR>", 'xt')
|
||||||
|
call assert_equal("\"hi link Aardig Aardig Aard\<Tab>", getreg(':'))
|
||||||
|
" hi link will complete to "NONE" for second parameter
|
||||||
|
call feedkeys(":hi link NON\<Tab>\<Home>\"\<CR>", 'xt')
|
||||||
|
call assert_equal("\"hi link NonText", getreg(':'))
|
||||||
|
call feedkeys(":hi link Aardig NON\<Tab>\<Home>\"\<CR>", 'xt')
|
||||||
|
call assert_equal("\"hi link Aardig NONE", getreg(':'))
|
||||||
|
|
||||||
" A cleared group does not show up in completions.
|
" A cleared group does not show up in completions.
|
||||||
hi Anders ctermfg=green
|
hi Anders ctermfg=green
|
||||||
@ -460,6 +477,102 @@ func Test_highlight_easter_egg()
|
|||||||
call test_override('ALL', 0)
|
call test_override('ALL', 0)
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_highlight_group_completion()
|
||||||
|
" Test completing keys
|
||||||
|
call assert_equal('term=', getcompletion('hi Foo ', 'cmdline')[0])
|
||||||
|
call assert_equal('ctermfg=', getcompletion('hi Foo c*fg', 'cmdline')[0])
|
||||||
|
call assert_equal('NONE', getcompletion('hi Foo NON', 'cmdline')[0])
|
||||||
|
set wildoptions+=fuzzy
|
||||||
|
call assert_equal('ctermbg=', getcompletion('hi Foo cmbg', 'cmdline')[0])
|
||||||
|
set wildoptions-=fuzzy
|
||||||
|
|
||||||
|
" Test completing the current value
|
||||||
|
hi FooBar term=bold,underline cterm=undercurl ctermfg=lightgray ctermbg=12 ctermul=34
|
||||||
|
call assert_equal('bold,underline', getcompletion('hi FooBar term=', 'cmdline')[0])
|
||||||
|
call assert_equal('undercurl', getcompletion('hi FooBar cterm=', 'cmdline')[0])
|
||||||
|
call assert_equal('7', getcompletion('hi FooBar ctermfg=', 'cmdline')[0])
|
||||||
|
call assert_equal('12', getcompletion('hi FooBar ctermbg=', 'cmdline')[0])
|
||||||
|
call assert_equal('34', getcompletion('hi FooBar ctermul=', 'cmdline')[0])
|
||||||
|
|
||||||
|
" "bold,underline" is unique and creates an extra item. "undercurl" and
|
||||||
|
" should be de-duplicated
|
||||||
|
call assert_equal(len(getcompletion('hi FooBar term=', 'cmdline')),
|
||||||
|
\ 1 + len(getcompletion('hi FooBar cterm=', 'cmdline')))
|
||||||
|
|
||||||
|
" don't complete original value if we have user input already, similar to
|
||||||
|
" behavior in :set <option>=<pattern>
|
||||||
|
call assert_equal(['bold'], getcompletion('hi FooBar term=bol', 'cmdline'))
|
||||||
|
call assert_equal([], getcompletion('hi FooBar ctermfg=1', 'cmdline'))
|
||||||
|
|
||||||
|
" start/stop do not fill their current value now as they are more
|
||||||
|
" complicated
|
||||||
|
hi FooBar start=123 stop=234
|
||||||
|
call assert_equal([], getcompletion('hi FooBar start=', 'cmdline'))
|
||||||
|
call assert_equal([], getcompletion('hi FooBar stop=', 'cmdline'))
|
||||||
|
|
||||||
|
if has("gui") || has("termguicolors")
|
||||||
|
hi FooBar gui=italic guifg=#112233 guibg=brown1 guisp=green
|
||||||
|
call assert_equal('italic', getcompletion('hi FooBar gui=', 'cmdline')[0])
|
||||||
|
call assert_equal('#112233', getcompletion('hi FooBar guifg=', 'cmdline')[0])
|
||||||
|
call assert_equal('brown1', getcompletion('hi FooBar guibg=', 'cmdline')[0])
|
||||||
|
call assert_equal('green', getcompletion('hi FooBar guisp=', 'cmdline')[0])
|
||||||
|
|
||||||
|
" Check that existing value is de-duplicated and doesn't show up later
|
||||||
|
call assert_equal(1, count(getcompletion('hi FooBar guibg=', 'cmdline'), 'brown1'))
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Test completing attributes
|
||||||
|
call assert_equal(['underdouble', 'underdotted'], getcompletion('hi DoesNotExist term=un*erdo*', 'cmdline'))
|
||||||
|
call assert_equal('NONE', getcompletion('hi DoesNotExist cterm=NON', 'cmdline')[0])
|
||||||
|
call assert_equal('NONE', getcompletion('hi DoesNotExist cterm=', 'cmdline')[-1]) " NONE should be at the end and not sorted
|
||||||
|
call assert_equal('bold', getcompletion('hi DoesNotExist cterm=underline,bo', 'cmdline')[0]) " complete after comma
|
||||||
|
if has("gui") || has("termguicolors")
|
||||||
|
set wildoptions+=fuzzy
|
||||||
|
call assert_equal('italic', getcompletion('hi DoesNotExist gui=itic', 'cmdline')[0])
|
||||||
|
set wildoptions-=fuzzy
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Test completing cterm colors
|
||||||
|
call assert_equal('fg', getcompletion('hi FooBar ctermbg=f*g', 'cmdline')[0])
|
||||||
|
call assert_equal('fg', getcompletion('hi DoesNotExist ctermbg=f*g', 'cmdline')[0])
|
||||||
|
call assert_equal('NONE', getcompletion('hi FooBar ctermfg=NON', 'cmdline')[0])
|
||||||
|
call assert_equal('NONE', getcompletion('hi DoesNotExist ctermfg=NON', 'cmdline')[0])
|
||||||
|
set wildoptions+=fuzzy
|
||||||
|
call assert_equal('Black', getcompletion('hi FooBar ctermul=blck', 'cmdline')[0])
|
||||||
|
call assert_equal('Black', getcompletion('hi DoesNotExist ctermul=blck', 'cmdline')[0])
|
||||||
|
set wildoptions-=fuzzy
|
||||||
|
|
||||||
|
" Test completing gui colors
|
||||||
|
if has("gui") || has("termguicolors")
|
||||||
|
call assert_equal('fg', getcompletion('hi FooBar guibg=f*g', 'cmdline')[0])
|
||||||
|
call assert_equal('fg', getcompletion('hi DoesNotExist guibg=f*g', 'cmdline')[0])
|
||||||
|
call assert_equal('NONE', getcompletion('hi FooBar guifg=NON', 'cmdline')[0])
|
||||||
|
call assert_equal('NONE', getcompletion('hi DoesNotExist guifg=NON', 'cmdline')[0])
|
||||||
|
set wildoptions=fuzzy
|
||||||
|
call assert_equal('limegreen', getcompletion('hi FooBar guisp=limgrn', 'cmdline')[0])
|
||||||
|
call assert_equal('limegreen', getcompletion('hi DoesNotExist guisp=limgrn', 'cmdline')[0])
|
||||||
|
set wildoptions-=fuzzy
|
||||||
|
|
||||||
|
" Test pruning bad color names with space. Vim doesn't support them.
|
||||||
|
let v:colornames['foobar with space'] = '#123456'
|
||||||
|
let v:colornames['foobarwithoutspace'] = '#234567'
|
||||||
|
call assert_equal(['foobarwithoutspace'], getcompletion('hi FooBar guibg=foobarw', 'cmdline'))
|
||||||
|
|
||||||
|
" Test specialized sorting. First few items are special values that
|
||||||
|
" go first, after that it's a sorted list of color names.
|
||||||
|
call assert_equal(['fg','bg','NONE'], getcompletion('hi DoesNotExist guifg=', 'cmdline')[0:2])
|
||||||
|
let completed_colors=getcompletion('hi DoesNotExist guifg=', 'cmdline')[3:]
|
||||||
|
let gui_colors_no_space=filter(copy(v:colornames), {key,val -> match(key, ' ')==-1})
|
||||||
|
call assert_equal(len(gui_colors_no_space), len(completed_colors))
|
||||||
|
call assert_equal(sort(copy(completed_colors)), completed_colors)
|
||||||
|
|
||||||
|
" Test that the specialized sorting still works if we have some pattern matches
|
||||||
|
let completed_colors=getcompletion('hi DoesNotExist guifg=*blue*', 'cmdline')
|
||||||
|
call assert_equal(sort(copy(completed_colors)), completed_colors)
|
||||||
|
call assert_equal('aliceblue', completed_colors[0])
|
||||||
|
endif
|
||||||
|
endfunc
|
||||||
|
|
||||||
func Test_getcompletion()
|
func Test_getcompletion()
|
||||||
let groupcount = len(getcompletion('', 'event'))
|
let groupcount = len(getcompletion('', 'event'))
|
||||||
call assert_true(groupcount > 0)
|
call assert_true(groupcount > 0)
|
||||||
|
|||||||
@ -209,7 +209,7 @@ endfunc
|
|||||||
|
|
||||||
func Test_echohl_completion()
|
func Test_echohl_completion()
|
||||||
call feedkeys(":echohl no\<C-A>\<C-B>\"\<CR>", 'tx')
|
call feedkeys(":echohl no\<C-A>\<C-B>\"\<CR>", 'tx')
|
||||||
call assert_equal('"echohl NonText Normal none', @:)
|
call assert_equal('"echohl NONE NonText Normal', @:)
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
func Test_syntax_arg_skipped()
|
func Test_syntax_arg_skipped()
|
||||||
|
|||||||
@ -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 */
|
||||||
|
/**/
|
||||||
|
1138,
|
||||||
/**/
|
/**/
|
||||||
1137,
|
1137,
|
||||||
/**/
|
/**/
|
||||||
|
|||||||
@ -846,6 +846,7 @@ extern int (*dyn_libintl_wputenv)(const wchar_t *envstring);
|
|||||||
#define EXPAND_DIRS_IN_CDPATH 59
|
#define EXPAND_DIRS_IN_CDPATH 59
|
||||||
#define EXPAND_SHELLCMDLINE 60
|
#define EXPAND_SHELLCMDLINE 60
|
||||||
#define EXPAND_FINDFUNC 61
|
#define EXPAND_FINDFUNC 61
|
||||||
|
#define EXPAND_HIGHLIGHT_GROUP 62
|
||||||
|
|
||||||
|
|
||||||
// Values for exmode_active (0 is no exmode)
|
// Values for exmode_active (0 is no exmode)
|
||||||
|
|||||||
Reference in New Issue
Block a user