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 <girishji@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/src/popupmenu.c b/src/popupmenu.c
index 44235ef..443223d 100644
--- a/src/popupmenu.c
+++ b/src/popupmenu.c
@@ -410,7 +410,7 @@
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 @@
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 @@
}
}
}
- 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 0000000..4423fd2
--- /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 2e9b32b..166c9da 100644
--- a/src/testdir/test_cmdline.vim
+++ b/src/testdir/test_cmdline.vim
@@ -2996,6 +2996,28 @@
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=<tab> 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\<tab>")
+ call VerifyScreenDump(buf, 'Test_wildmenu_pum_hl_match_nonf', {})
+ call term_sendkeys(buf, "\<Esc>")
+ 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 3d5f869..1a23fe9 100644
--- a/src/version.c
+++ b/src/version.c
@@ -705,6 +705,8 @@
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1170,
+/**/
1169,
/**/
1168,