From 4ec46f32102e5569b247840e05a99221747a9381 Mon Sep 17 00:00:00 2001 From: Girish Palya Date: Tue, 4 Mar 2025 20:56:30 +0100 Subject: [PATCH] patch 9.1.1170: wildmenu highlighting in popup can be improved Problem: wildmenu highlighting in popup can be improved Solution: Check if the completion items contain submatches of the entered text (Girish Palya). This update enables highlighting in the popup menu even when the matched fragment or pattern appears within an item (string) rather than only at the beginning. This is especially useful for custom completion, where menu items may not always start with the typed pattern. For specific use cases, refer to the two examples in https://github.com/vim/vim/pull/16759 A sliding window approach is used with direct string comparison. Performance is not a concern, as highlighting is applied only to displayed lines, even if the menu list is arbitrarily long. closes: #16785 Signed-off-by: Girish Palya Signed-off-by: Christian Brabandt --- src/popupmenu.c | 16 +++++++++----- .../Test_wildmenu_pum_hl_match_nonf.dump | 10 +++++++++ src/testdir/test_cmdline.vim | 22 +++++++++++++++++++ src/version.c | 2 ++ 4 files changed, 44 insertions(+), 6 deletions(-) create mode 100644 src/testdir/dumps/Test_wildmenu_pum_hl_match_nonf.dump diff --git a/src/popupmenu.c b/src/popupmenu.c index 44235efbd7..443223de71 100644 --- a/src/popupmenu.c +++ b/src/popupmenu.c @@ -410,7 +410,7 @@ pum_compute_text_attrs(char_u *text, hlf_T hlf, int user_hlattr) int *attrs = NULL; char_u *leader = NULL; int in_fuzzy; - int matched_start = FALSE; + int matched_len = -1; int_u char_pos = 0; int is_select = FALSE; @@ -435,8 +435,6 @@ pum_compute_text_attrs(char_u *text, hlf_T hlf, int user_hlattr) if (in_fuzzy) ga = fuzzy_match_str_with_pos(text, leader); - else - matched_start = MB_STRNICMP(text, leader, leader_len) == 0; while (*ptr != NUL) { @@ -455,10 +453,16 @@ pum_compute_text_attrs(char_u *text, hlf_T hlf, int user_hlattr) } } } - else if (matched_start && ptr < text + leader_len) + else { - new_attr = highlight_attr[is_select ? HLF_PMSI : HLF_PMNI]; - new_attr = hl_combine_attr(highlight_attr[hlf], new_attr); + if (matched_len < 0 && MB_STRNICMP(ptr, leader, leader_len) == 0) + matched_len = leader_len; + if (matched_len > 0) + { + new_attr = highlight_attr[is_select ? HLF_PMSI : HLF_PMNI]; + new_attr = hl_combine_attr(highlight_attr[hlf], new_attr); + matched_len--; + } } new_attr = hl_combine_attr(highlight_attr[HLF_PNI], new_attr); diff --git a/src/testdir/dumps/Test_wildmenu_pum_hl_match_nonf.dump b/src/testdir/dumps/Test_wildmenu_pum_hl_match_nonf.dump new file mode 100644 index 0000000000..4423fd2ae0 --- /dev/null +++ b/src/testdir/dumps/Test_wildmenu_pum_hl_match_nonf.dump @@ -0,0 +1,10 @@ +| +0&#ffffff0@49 +|~+0#4040ff13&| @48 +|~| @48 +|~| @48 +|~| @48 +|~| @48 +|~| @4| +0#0000001#ffd7ff255|o|n+0#0000e05&|e|A+0#0000001&| @10| +0#4040ff13#ffffff0@27 +|~| @4| +0#0000001#ffd7ff255|o| |n+0#0000e05&|e|B+0#0000001&|n|e|B| @6| +0#4040ff13#ffffff0@27 +|~| @4| +0#0000001#ffd7ff255|a|o|n+0#0000e05&|e|C+0#0000001&| @9| +0#4040ff13#ffffff0@27 +|:+0#0000000&|M|y|C|m|d| |n|e> @40 diff --git a/src/testdir/test_cmdline.vim b/src/testdir/test_cmdline.vim index 2e9b32bc4f..166c9da87f 100644 --- a/src/testdir/test_cmdline.vim +++ b/src/testdir/test_cmdline.vim @@ -2996,6 +2996,28 @@ func Test_wildmenu_pum_rightleft() call StopVimInTerminal(buf) endfunc +" Test highlighting when pattern matches non-first character of item +func Test_wildmenu_pum_hl_nonfirst() + CheckScreendump + let lines =<< trim END + set wildoptions=pum wildchar= wildmode=noselect,full + hi PmenuMatchSel ctermfg=6 ctermbg=7 + hi PmenuMatch ctermfg=4 ctermbg=225 + func T(a, c, p) + return ["oneA", "o neBneB", "aoneC"] + endfunc + command -nargs=1 -complete=customlist,T MyCmd + END + + call writefile(lines, 'Xwildmenu_pum_hl_nonf', 'D') + let buf = RunVimInTerminal('-S Xwildmenu_pum_hl_nonf', #{rows: 10, cols: 50}) + + call term_sendkeys(buf, ":MyCmd ne\") + call VerifyScreenDump(buf, 'Test_wildmenu_pum_hl_match_nonf', {}) + call term_sendkeys(buf, "\") + call StopVimInTerminal(buf) +endfunc + " Test highlighting matched text in cmdline completion popup menu. func Test_wildmenu_pum_hl_match() CheckScreendump diff --git a/src/version.c b/src/version.c index 3d5f869381..1a23fe9412 100644 --- a/src/version.c +++ b/src/version.c @@ -704,6 +704,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1170, /**/ 1169, /**/ -- 2.47.2