aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2025-03-05 06:51:36 +0800
committerGitHub <noreply@github.com>2025-03-04 22:51:36 +0000
commitb0341136c1c92790d599ae361d0d91952a52f0a2 (patch)
treeb19c6acd9be3df4457405ead1ac58349c524df40
parent97dc02687af76981fa202cb575445d670b66f1f1 (diff)
downloadrneovim-b0341136c1c92790d599ae361d0d91952a52f0a2.tar.gz
rneovim-b0341136c1c92790d599ae361d0d91952a52f0a2.tar.bz2
rneovim-b0341136c1c92790d599ae361d0d91952a52f0a2.zip
vim-patch:9.1.1170: wildmenu highlighting in popup can be improved (#32728)
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: vim/vim#16785 https://github.com/vim/vim/commit/4ec46f32102e5569b247840e05a99221747a9381 Co-authored-by: Girish Palya <girishji@gmail.com>
-rw-r--r--src/nvim/popupmenu.c18
-rw-r--r--test/functional/ui/popupmenu_spec.lua23
-rw-r--r--test/old/testdir/test_cmdline.vim22
3 files changed, 56 insertions, 7 deletions
diff --git a/src/nvim/popupmenu.c b/src/nvim/popupmenu.c
index 2e533bea23..3860ba8f6a 100644
--- a/src/nvim/popupmenu.c
+++ b/src/nvim/popupmenu.c
@@ -430,12 +430,10 @@ static int *pum_compute_text_attrs(char *text, hlf_T hlf, int user_hlattr)
size_t leader_len = strlen(leader);
garray_T *ga = NULL;
- bool matched_start = false;
+ int matched_len = -1;
if (in_fuzzy) {
ga = fuzzy_match_str_with_pos(text, leader);
- } else {
- matched_start = mb_strnicmp(text, leader, leader_len) == 0;
}
const char *ptr = text;
@@ -456,10 +454,16 @@ static int *pum_compute_text_attrs(char *text, hlf_T hlf, int user_hlattr)
break;
}
}
- } else if (matched_start && ptr < text + leader_len) {
- new_attr = win_hl_attr(curwin, is_select ? HLF_PMSI : HLF_PMNI);
- new_attr = hl_combine_attr(win_hl_attr(curwin, HLF_PMNI), new_attr);
- new_attr = hl_combine_attr(win_hl_attr(curwin, (int)hlf), new_attr);
+ } else {
+ if (matched_len < 0 && mb_strnicmp(ptr, leader, leader_len) == 0) {
+ matched_len = (int)leader_len;
+ }
+ if (matched_len > 0) {
+ new_attr = win_hl_attr(curwin, is_select ? HLF_PMSI : HLF_PMNI);
+ new_attr = hl_combine_attr(win_hl_attr(curwin, HLF_PMNI), new_attr);
+ new_attr = hl_combine_attr(win_hl_attr(curwin, (int)hlf), new_attr);
+ matched_len--;
+ }
}
new_attr = hl_combine_attr(win_hl_attr(curwin, HLF_PNI), new_attr);
diff --git a/test/functional/ui/popupmenu_spec.lua b/test/functional/ui/popupmenu_spec.lua
index f6c9236037..0206900c06 100644
--- a/test/functional/ui/popupmenu_spec.lua
+++ b/test/functional/ui/popupmenu_spec.lua
@@ -5145,6 +5145,29 @@ describe('builtin popupmenu', function()
]])
end)
+ -- oldtest: Test_wildmenu_pum_hl_nonfirst()
+ it('highlight matched text in the middle in cmdline pum', function()
+ exec([[
+ set wildoptions=pum wildchar=<tab> wildmode=noselect,full
+ hi PmenuMatchSel guifg=Blue guibg=Grey
+ hi PmenuMatch guifg=Blue guibg=Plum1
+ func T(a, c, p)
+ return ["oneA", "o neBneB", "aoneC"]
+ endfunc
+ command -nargs=1 -complete=customlist,T MyCmd
+ ]])
+
+ feed(':MyCmd ne<tab>')
+ screen:expect([[
+ |
+ {1:~ }|*15
+ {1:~ }{n: o}{mn:ne}{n:A }{1: }|
+ {1:~ }{n: o }{mn:ne}{n:BneB }{1: }|
+ {1:~ }{n: ao}{mn:ne}{n:C }{1: }|
+ :MyCmd ne^ |
+ ]])
+ end)
+
it(
'cascading highlights for matched text (PmenuMatch, PmenuMatchSel) in cmdline pum',
function()
diff --git a/test/old/testdir/test_cmdline.vim b/test/old/testdir/test_cmdline.vim
index d9496ba2a6..639a4c1d32 100644
--- a/test/old/testdir/test_cmdline.vim
+++ b/test/old/testdir/test_cmdline.vim
@@ -3025,6 +3025,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=<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