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:
Yee Cheng Chin
2025-02-23 09:32:47 +01:00
committed by Christian Brabandt
parent f4b36417e8
commit a7b8120820
12 changed files with 627 additions and 89 deletions

View File

@ -3221,6 +3221,8 @@ ExpandFromContext(
ret = ExpandMappings(pat, &regmatch, numMatches, matches);
else if (xp->xp_context == EXPAND_ARGOPT)
ret = expand_argopt(pat, xp, &regmatch, matches, numMatches);
else if (xp->xp_context == EXPAND_HIGHLIGHT_GROUP)
ret = expand_highlight_group(pat, xp, &regmatch, matches, numMatches);
#if defined(FEAT_TERMINAL)
else if (xp->xp_context == EXPAND_TERMINALOPT)
ret = expand_terminal_opt(pat, xp, &regmatch, matches, numMatches);
@ -3239,18 +3241,6 @@ ExpandFromContext(
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
ExpandGeneric(
char_u *pat,
@ -3261,6 +3251,38 @@ ExpandGeneric(
char_u *((*func)(expand_T *, int)),
// returns a string from the list
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;
garray_T ga;
@ -3271,6 +3293,7 @@ ExpandGeneric(
int match;
int sort_matches = FALSE;
int funcsort = FALSE;
int sortStartMatchIdx = -1;
fuzzy = cmdline_fuzzy_complete(pat);
*matches = NULL;
@ -3346,6 +3369,12 @@ ExpandGeneric(
}
#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;
}
@ -3371,14 +3400,14 @@ ExpandGeneric(
funcsort = TRUE;
// Sort the matches.
if (sort_matches)
if (sort_matches && sortStartMatchIdx != -1)
{
if (funcsort)
// <SNR> functions should be sorted to the end.
qsort((void *)ga.ga_data, (size_t)ga.ga_len, sizeof(char_u *),
sort_func_compare);
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)