]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.1.1170: wildmenu highlighting in popup can be improved v9.1.1170
authorGirish Palya <girishji@gmail.com>
Tue, 4 Mar 2025 19:56:30 +0000 (20:56 +0100)
committerChristian Brabandt <cb@256bit.org>
Tue, 4 Mar 2025 19:56:30 +0000 (20:56 +0100)
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>
src/popupmenu.c
src/testdir/dumps/Test_wildmenu_pum_hl_match_nonf.dump [new file with mode: 0644]
src/testdir/test_cmdline.vim
src/version.c

index 44235efbd7dc7fc70f9c57f87a7052bbe20e9ce4..443223de712ffd92ce2ec2d917a6a5cd3a3d9f1e 100644 (file)
@@ -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 (file)
index 0000000..4423fd2
--- /dev/null
@@ -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
index 2e9b32bc4fb5202eead6bde97ebdce3589a1a9e4..166c9da87fb1f79be2d3c081d937568aca260bd2 100644 (file)
@@ -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=<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
index 3d5f8693810fc26b5975d6719469abe883dced61..1a23fe9412dace9c8d3780dadb4719cbb0c45a9a 100644 (file)
@@ -704,6 +704,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1170,
 /**/
     1169,
 /**/