1
0
forked from aniani/vim

patch 9.1.0690: cannot set special highlight kind in popupmenu

Problem:  cannot set special highlight kind in popupmenu
Solution: add kind_hlgroup item to complete function
          (glepnir)

closes: #15561

Signed-off-by: glepnir <glephunter@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
glepnir 2024-08-23 18:31:06 +02:00 committed by Christian Brabandt
parent 56186e41db
commit 38f99a1f0d
No known key found for this signature in database
GPG Key ID: F3F92DA383FDDE09
8 changed files with 94 additions and 11 deletions

View File

@ -1,4 +1,4 @@
*insert.txt* For Vim version 9.1. Last change: 2024 Jul 28 *insert.txt* For Vim version 9.1. Last change: 2024 Aug 23
VIM REFERENCE MANUAL by Bram Moolenaar VIM REFERENCE MANUAL by Bram Moolenaar
@ -1189,6 +1189,11 @@ items:
attributes in the popup menu to apply cterm and gui attributes in the popup menu to apply cterm and gui
properties (with higher priority) like strikethrough properties (with higher priority) like strikethrough
to the completion items to the completion items
kind_hlgroup an additional highlight group specifically for setting
the highlight attributes of the completion kind. When
this field is present, it will override the |hl-PmenuKind|
highlight group, allowing for the customization of
ctermfd and guifg properties for the completion kind
All of these except "icase", "equal", "dup" and "empty" must be a string. If All of these except "icase", "equal", "dup" and "empty" must be a string. If
an item does not meet these requirements then an error message is given and an item does not meet these requirements then an error message is given and

View File

@ -1,4 +1,4 @@
*version9.txt* For Vim version 9.1. Last change: 2024 Aug 15 *version9.txt* For Vim version 9.1. Last change: 2024 Aug 23
VIM REFERENCE MANUAL by Bram Moolenaar VIM REFERENCE MANUAL by Bram Moolenaar
@ -41563,6 +41563,9 @@ Support for the XDG Desktop Specification |xdg-base-dir|
Support highlighting the matched text for insert-mode completion and Support highlighting the matched text for insert-mode completion and
command-line completion in |ins-completion-menu|. command-line completion in |ins-completion-menu|.
Support highlighting the completion kind in |ins-completion-menu|, see
|complete-items|.
Support for translating messages in Vim script plugins using the |gettext()| Support for translating messages in Vim script plugins using the |gettext()|
and |bindtextdomain()| functions. and |bindtextdomain()| functions.

View File

@ -115,6 +115,7 @@ struct compl_S
int cp_number; // sequence number int cp_number; // sequence number
int cp_score; // fuzzy match score int cp_score; // fuzzy match score
int cp_user_hlattr; // highlight attribute to combine with int cp_user_hlattr; // highlight attribute to combine with
int cp_user_kind_hlattr; // highlight attribute for kind
}; };
// values for cp_flags // values for cp_flags
@ -206,7 +207,7 @@ static int compl_selected_item = -1;
static int *compl_fuzzy_scores; static int *compl_fuzzy_scores;
static int ins_compl_add(char_u *str, int len, char_u *fname, char_u **cptext, typval_T *user_data, int cdir, int flags, int adup, int user_hlattr); static int ins_compl_add(char_u *str, int len, char_u *fname, char_u **cptext, typval_T *user_data, int cdir, int flags, int adup, int user_hlattr, int user_kind_hlattr);
static void ins_compl_longest_match(compl_T *match); static void ins_compl_longest_match(compl_T *match);
static void ins_compl_del_pum(void); static void ins_compl_del_pum(void);
static void ins_compl_files(int count, char_u **files, int thesaurus, int flags, regmatch_T *regmatch, char_u *buf, int *dir); static void ins_compl_files(int count, char_u **files, int thesaurus, int flags, regmatch_T *regmatch, char_u *buf, int *dir);
@ -746,7 +747,7 @@ ins_compl_add_infercase(
if (icase) if (icase)
flags |= CP_ICASE; flags |= CP_ICASE;
res = ins_compl_add(str, len, fname, NULL, NULL, dir, flags, FALSE, -1); res = ins_compl_add(str, len, fname, NULL, NULL, dir, flags, FALSE, -1, -1);
vim_free(tofree); vim_free(tofree);
return res; return res;
} }
@ -780,7 +781,8 @@ ins_compl_add(
int cdir, int cdir,
int flags_arg, int flags_arg,
int adup, // accept duplicate match int adup, // accept duplicate match
int user_hlattr) int user_hlattr,
int user_kind_hlattr)
{ {
compl_T *match; compl_T *match;
int dir = (cdir == 0 ? compl_direction : cdir); int dir = (cdir == 0 ? compl_direction : cdir);
@ -845,6 +847,7 @@ ins_compl_add(
match->cp_fname = NULL; match->cp_fname = NULL;
match->cp_flags = flags; match->cp_flags = flags;
match->cp_user_hlattr = user_hlattr; match->cp_user_hlattr = user_hlattr;
match->cp_user_kind_hlattr = user_kind_hlattr;
if (cptext != NULL) if (cptext != NULL)
{ {
@ -997,7 +1000,7 @@ ins_compl_add_matches(
for (i = 0; i < num_matches && add_r != FAIL; i++) for (i = 0; i < num_matches && add_r != FAIL; i++)
if ((add_r = ins_compl_add(matches[i], -1, NULL, NULL, NULL, dir, if ((add_r = ins_compl_add(matches[i], -1, NULL, NULL, NULL, dir,
CP_FAST | (icase ? CP_ICASE : 0), FALSE, -1)) == OK) CP_FAST | (icase ? CP_ICASE : 0), FALSE, -1, -1)) == OK)
// if dir was BACKWARD then honor it just once // if dir was BACKWARD then honor it just once
dir = FORWARD; dir = FORWARD;
FreeWild(num_matches, matches); FreeWild(num_matches, matches);
@ -1343,6 +1346,7 @@ ins_compl_build_pum(void)
compl_match_array[i].pum_info = compl->cp_text[CPT_INFO]; compl_match_array[i].pum_info = compl->cp_text[CPT_INFO];
compl_match_array[i].pum_score = compl->cp_score; compl_match_array[i].pum_score = compl->cp_score;
compl_match_array[i].pum_user_hlattr = compl->cp_user_hlattr; compl_match_array[i].pum_user_hlattr = compl->cp_user_hlattr;
compl_match_array[i].pum_user_kind_hlattr = compl->cp_user_kind_hlattr;
if (compl->cp_text[CPT_MENU] != NULL) if (compl->cp_text[CPT_MENU] != NULL)
compl_match_array[i++].pum_extra = compl_match_array[i++].pum_extra =
compl->cp_text[CPT_MENU]; compl->cp_text[CPT_MENU];
@ -2844,6 +2848,14 @@ theend:
#endif // FEAT_COMPL_FUNC #endif // FEAT_COMPL_FUNC
#if defined(FEAT_COMPL_FUNC) || defined(FEAT_EVAL) || defined(PROTO) #if defined(FEAT_COMPL_FUNC) || defined(FEAT_EVAL) || defined(PROTO)
static inline int
get_user_highlight_attr(char_u *hlname)
{
if (hlname != NULL && *hlname != NUL)
return syn_name2attr(hlname);
return -1;
}
/* /*
* Add a match to the list of matches from a typeval_T. * Add a match to the list of matches from a typeval_T.
* If the given string is already in the list of completions, then return * If the given string is already in the list of completions, then return
@ -2862,7 +2874,9 @@ ins_compl_add_tv(typval_T *tv, int dir, int fast)
typval_T user_data; typval_T user_data;
int status; int status;
char_u *user_hlname; char_u *user_hlname;
char_u *user_kind_hlname;
int user_hlattr = -1; int user_hlattr = -1;
int user_kind_hlattr = -1;
user_data.v_type = VAR_UNKNOWN; user_data.v_type = VAR_UNKNOWN;
if (tv->v_type == VAR_DICT && tv->vval.v_dict != NULL) if (tv->v_type == VAR_DICT && tv->vval.v_dict != NULL)
@ -2872,9 +2886,12 @@ ins_compl_add_tv(typval_T *tv, int dir, int fast)
cptext[CPT_MENU] = dict_get_string(tv->vval.v_dict, "menu", FALSE); cptext[CPT_MENU] = dict_get_string(tv->vval.v_dict, "menu", FALSE);
cptext[CPT_KIND] = dict_get_string(tv->vval.v_dict, "kind", FALSE); cptext[CPT_KIND] = dict_get_string(tv->vval.v_dict, "kind", FALSE);
cptext[CPT_INFO] = dict_get_string(tv->vval.v_dict, "info", FALSE); cptext[CPT_INFO] = dict_get_string(tv->vval.v_dict, "info", FALSE);
user_hlname = dict_get_string(tv->vval.v_dict, "hl_group", FALSE); user_hlname = dict_get_string(tv->vval.v_dict, "hl_group", FALSE);
if (user_hlname != NULL && *user_hlname != NUL) user_hlattr = get_user_highlight_attr(user_hlname);
user_hlattr = syn_name2attr(user_hlname);
user_kind_hlname = dict_get_string(tv->vval.v_dict, "kind_hlgroup", FALSE);
user_kind_hlattr = get_user_highlight_attr(user_kind_hlname);
dict_get_tv(tv->vval.v_dict, "user_data", &user_data); dict_get_tv(tv->vval.v_dict, "user_data", &user_data);
if (dict_get_string(tv->vval.v_dict, "icase", FALSE) != NULL if (dict_get_string(tv->vval.v_dict, "icase", FALSE) != NULL
@ -2899,7 +2916,7 @@ ins_compl_add_tv(typval_T *tv, int dir, int fast)
return FAIL; return FAIL;
} }
status = ins_compl_add(word, -1, NULL, cptext, status = ins_compl_add(word, -1, NULL, cptext,
&user_data, dir, flags, dup, user_hlattr); &user_data, dir, flags, dup, user_hlattr, user_kind_hlattr);
if (status != OK) if (status != OK)
clear_tv(&user_data); clear_tv(&user_data);
return status; return status;
@ -2986,7 +3003,7 @@ set_completion(colnr_T startcol, list_T *list)
flags |= CP_ICASE; flags |= CP_ICASE;
if (compl_orig_text == NULL || ins_compl_add(compl_orig_text, if (compl_orig_text == NULL || ins_compl_add(compl_orig_text,
-1, NULL, NULL, NULL, 0, -1, NULL, NULL, NULL, 0,
flags | CP_FAST, FALSE, -1) != OK) flags | CP_FAST, FALSE, -1, -1) != OK)
return; return;
ctrl_x_mode = CTRL_X_EVAL; ctrl_x_mode = CTRL_X_EVAL;
@ -5218,7 +5235,7 @@ ins_compl_start(void)
if (p_ic) if (p_ic)
flags |= CP_ICASE; flags |= CP_ICASE;
if (compl_orig_text == NULL || ins_compl_add(compl_orig_text, if (compl_orig_text == NULL || ins_compl_add(compl_orig_text,
-1, NULL, NULL, NULL, 0, flags, FALSE, -1) != OK) -1, NULL, NULL, NULL, 0, flags, FALSE, -1, -1) != OK)
{ {
VIM_CLEAR(compl_pattern); VIM_CLEAR(compl_pattern);
compl_patternlen = 0; compl_patternlen = 0;

View File

@ -633,6 +633,8 @@ pum_redraw(void)
attr = highlight_attr[hlf]; attr = highlight_attr[hlf];
if (pum_array[idx].pum_user_hlattr > 0) if (pum_array[idx].pum_user_hlattr > 0)
attr = hl_combine_attr(attr, pum_array[idx].pum_user_hlattr); attr = hl_combine_attr(attr, pum_array[idx].pum_user_hlattr);
if (round == 1 && pum_array[idx].pum_user_kind_hlattr > 0)
attr = hl_combine_attr(attr, pum_array[idx].pum_user_kind_hlattr);
width = 0; width = 0;
s = NULL; s = NULL;
switch (round) switch (round)

View File

@ -4475,6 +4475,7 @@ typedef struct
int pum_score; // fuzzy match score int pum_score; // fuzzy match score
int pum_idx; // index of item before sorting by score int pum_idx; // index of item before sorting by score
int pum_user_hlattr; // highlight attribute to combine with int pum_user_hlattr; // highlight attribute to combine with
int pum_user_kind_hlattr; // highlight attribute for kind
} pumitem_T; } pumitem_T;
/* /*

View File

@ -0,0 +1,20 @@
|a+0&#ffffff0|w|o|r|d|1> @68
|a+0#ff404010#e0e0e08|w|o|r|d|1| |v+0#ffff4012&|a|r|i|a|b|l|e| |e+0#ff404010&|x|t|r|a| |t|e|x|t| |1| | +0#4040ff13#ffffff0@45
|a+0#0000001#ffd7ff255|w|o|r|d|2| |f+0#4040ff13&|u|n|c|t|i|o|n| |e+0#0000001&|x|t|r|a| |t|e|x|t| |2| | +0#4040ff13#ffffff0@45
|你*0#0000001#ffd7ff255|好| +&@2|c+0#40ff4011&|l|a|s@1| @3|e+0#0000001&|x|t|r|a| |t|e|x|t| |3| | +0#4040ff13#ffffff0@45
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|~| @73
|-+2#0000000&@1| |U|s|e|r| |d|e|f|i|n|e|d| |c|o|m|p|l|e|t|i|o|n| |(|^|U|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |1| |o|f| |3| +0#0000000&@26

View File

@ -1548,4 +1548,37 @@ func Test_pum_user_hl_group()
call StopVimInTerminal(buf) call StopVimInTerminal(buf)
endfunc endfunc
func Test_pum_user_kind_hlgroup()
CheckScreendump
let lines =<< trim END
func CompleteFunc( findstart, base )
if a:findstart
return 0
endif
return {
\ 'words': [
\ { 'word': 'aword1', 'menu': 'extra text 1', 'kind': 'variable', 'kind_hlgroup': 'KindVar', 'hl_group': 'StrikeFake' },
\ { 'word': 'aword2', 'menu': 'extra text 2', 'kind': 'function', 'kind_hlgroup': 'KindFunc' },
\ { 'word': '你好', 'menu': 'extra text 3', 'kind': 'class', 'kind_hlgroup': 'KindClass' },
\]}
endfunc
set completeopt=menu
set completefunc=CompleteFunc
hi StrikeFake ctermfg=9
hi KindVar ctermfg=yellow
hi KindFunc ctermfg=blue
hi KindClass ctermfg=green
END
call writefile(lines, 'Xscript', 'D')
let buf = RunVimInTerminal('-S Xscript', {})
call TermWait(buf)
call term_sendkeys(buf, "S\<C-X>\<C-U>")
call VerifyScreenDump(buf, 'Test_pum_highlights_16', {})
call term_sendkeys(buf, "\<C-E>\<Esc>")
call StopVimInTerminal(buf)
endfunc
" vim: shiftwidth=2 sts=2 expandtab " vim: shiftwidth=2 sts=2 expandtab

View File

@ -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 */
/**/
690,
/**/ /**/
689, 689,
/**/ /**/