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>
diff --git a/src/cmdexpand.c b/src/cmdexpand.c
index f707b1d..c14eee2 100644
--- a/src/cmdexpand.c
+++ b/src/cmdexpand.c
@@ -3221,6 +3221,8 @@
ret = ExpandMappings(pat, ®match, numMatches, matches);
else if (xp->xp_context == EXPAND_ARGOPT)
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)
else if (xp->xp_context == EXPAND_TERMINALOPT)
ret = expand_terminal_opt(pat, xp, ®match, matches, numMatches);
@@ -3239,18 +3241,6 @@
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,
@@ -3262,6 +3252,38 @@
// 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;
char_u *str;
@@ -3271,6 +3293,7 @@
int match;
int sort_matches = FALSE;
int funcsort = FALSE;
+ int sortStartMatchIdx = -1;
fuzzy = cmdline_fuzzy_complete(pat);
*matches = NULL;
@@ -3346,6 +3369,12 @@
}
#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 @@
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)