]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.1.0476: Cannot see matched text in popup menu v9.1.0476
authorglepnir <glephunter@gmail.com>
Tue, 11 Jun 2024 17:37:04 +0000 (19:37 +0200)
committerChristian Brabandt <cb@256bit.org>
Tue, 11 Jun 2024 17:40:50 +0000 (19:40 +0200)
Problem:  Cannot see matched text in popup menu
Solution: Introduce 2 new highlighting groups: PmenuMatch and
          PmenuMatchSel (glepnir)

ping @habamax, @neutaaaaan @romainl because vim/colorschemes may need
some updates, @lifepillar for updating vim-colortemplate

closes: #14694

Signed-off-by: glepnir <glephunter@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
19 files changed:
runtime/doc/options.txt
runtime/doc/syntax.txt
runtime/doc/tags
runtime/doc/version9.txt
src/highlight.c
src/insexpand.c
src/optiondefs.h
src/popupmenu.c
src/proto/insexpand.pro
src/proto/search.pro
src/search.c
src/testdir/dumps/Test_pum_highlights_03.dump [new file with mode: 0644]
src/testdir/dumps/Test_pum_highlights_04.dump [new file with mode: 0644]
src/testdir/dumps/Test_pum_highlights_05.dump [new file with mode: 0644]
src/testdir/dumps/Test_pum_highlights_06.dump [new file with mode: 0644]
src/testdir/dumps/Test_pum_highlights_07.dump [new file with mode: 0644]
src/testdir/test_popup.vim
src/version.c
src/vim.h

index 655fd6c52424581ef20f59c9d26a1f0dd415074f..6849bc3caa57fc9660f93d24bd0c5cbe1807e68c 100644 (file)
@@ -1,4 +1,4 @@
-*options.txt*  For Vim version 9.1.  Last change: 2024 Jun 05
+*options.txt*  For Vim version 9.1.  Last change: 2024 Jun 11
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -4275,6 +4275,7 @@ A jump table for the options with a short description can be found at |Q_op|.
                                     T:DiffText,>:SignColumn,-:Conceal,
                                     B:SpellBad,P:SpellCap,R:SpellRare,
                                     L:SpellLocal,+:Pmenu,=:PmenuSel,
+                                    k:PmenuMatch,<:PmenuMatchSel,
                                     [:PmenuKind,]:PmenuKindSel,
                                     {:PmenuExtra,}:PmenuExtraSel,
                                     x:PmenuSbar,X:PmenuThumb,*:TabLine,
@@ -4341,6 +4342,8 @@ A jump table for the options with a short description can be found at |Q_op|.
        |hl-PmenuExtraSel| }  popup menu "extra" selected line
        |hl-PmenuSbar|   x  popup menu scrollbar
        |hl-PmenuThumb|  X  popup menu scrollbar thumb
+       |hl-PmenuMatch|  k  popup menu matched text
+       |hl-PmenuMatchSel| <  popup menu matched text in selected line
 
        The display modes are:
                r       reverse         (termcap entry "mr" and "me")
index b6b3d8e6ed71a20874cb08c9c4d13c1cb58f1cc0..9d8af85f6759d04eae7a2e77105a41fa5656b284 100644 (file)
@@ -1,4 +1,4 @@
-*syntax.txt*   For Vim version 9.1.  Last change: 2024 Jun 09
+*syntax.txt*   For Vim version 9.1.  Last change: 2024 Jun 11
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -5681,6 +5681,11 @@ PmenuExtraSel    Popup menu: Selected item "extra text".
 PmenuSbar      Popup menu: Scrollbar.
                                                        *hl-PmenuThumb*
 PmenuThumb     Popup menu: Thumb of the scrollbar.
+                                                       *hl-PmenuMatch*
+PmenuMatch     Popup menu: Matched text in normal item
+                                                       *hl-PmenuMatchSel*
+PmenuMatchSel  Popup menu: Matched text in selected item
+
                                                        *hl-PopupNotification*
 PopupNotification
                Popup window created with |popup_notification()|.  If not
index 96be83ab0f667ed4890374630aaa8c14168b075a..3085ccc4ca375b0c8073d034f27e97255164e94f 100644 (file)
@@ -8090,6 +8090,8 @@ hl-PmenuExtra     syntax.txt      /*hl-PmenuExtra*
 hl-PmenuExtraSel       syntax.txt      /*hl-PmenuExtraSel*
 hl-PmenuKind   syntax.txt      /*hl-PmenuKind*
 hl-PmenuKindSel        syntax.txt      /*hl-PmenuKindSel*
+hl-PmenuMatch  syntax.txt      /*hl-PmenuMatch*
+hl-PmenuMatchSel       syntax.txt      /*hl-PmenuMatchSel*
 hl-PmenuSbar   syntax.txt      /*hl-PmenuSbar*
 hl-PmenuSel    syntax.txt      /*hl-PmenuSel*
 hl-PmenuThumb  syntax.txt      /*hl-PmenuThumb*
index 6edb8891bcb6bf36b2e174e6f27a4264dacfeebc..28dd7a3ad9d6b6fb15d7bc6e69fd1ad707b569e1 100644 (file)
@@ -1,4 +1,4 @@
-*version9.txt*  For Vim version 9.1.  Last change: 2024 Jun 05
+*version9.txt*  For Vim version 9.1.  Last change: 2024 Jun 10
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -41596,6 +41596,9 @@ Autocommands: ~
 Highlighting: ~
 
 |hl-MsgArea|           highlighting of the Command-line and messages area
+|hl-PmenuMatch|                Popup menu: highlighting of matched text
+|hl-PmenuMatchSel|             Popup menu: highlighting of matched text in selected
+                       line
 
 Commands: ~
 
index 9aa149ff9cbde121aa4b91fc97b06323a83139f4..a71a100dcdd68ff3ecb7d35fdf458c137765f14d 100644 (file)
@@ -258,6 +258,8 @@ static char *(highlight_init_both[]) = {
     "default link CurSearch Search",
     "default link PmenuKind Pmenu",
     "default link PmenuKindSel PmenuSel",
+    "default link PmenuMatch Pmenu",
+    "default link PmenuMatchSel PmenuSel",
     "default link PmenuExtra Pmenu",
     "default link PmenuExtraSel PmenuSel",
     CENT("Normal cterm=NONE", "Normal gui=NONE"),
index 19a4a217377bd6d009748ce1b3027ded965b99aa..74be94cf4b9149543158336f0bd5df8ac1fd429e 100644 (file)
@@ -1431,6 +1431,15 @@ ins_compl_show_pum(void)
 #define DICT_FIRST     (1)     // use just first element in "dict"
 #define DICT_EXACT     (2)     // "dict" is the exact name of a file
 
+/*
+ * Get current completion leader
+ */
+    char_u *
+ins_compl_leader(void)
+{
+    return compl_leader;
+}
+
 /*
  * Add any identifiers that match the given pattern "pat" in the list of
  * dictionary files "dict_start" to the list of completions.
index 7b58f6b3330d5946c8244fbeea1aec1b34d12d79..617f3cec6bfbf994b62ace91a8c3c2d9b24a1a4f 100644 (file)
@@ -301,7 +301,7 @@ struct vimoption
 # define ISP_LATIN1 (char_u *)"@,161-255"
 #endif
 
-# define HIGHLIGHT_INIT "8:SpecialKey,~:EndOfBuffer,@:NonText,d:Directory,e:ErrorMsg,i:IncSearch,l:Search,y:CurSearch,m:MoreMsg,M:ModeMsg,n:LineNr,a:LineNrAbove,b:LineNrBelow,N:CursorLineNr,G:CursorLineSign,O:CursorLineFold,r:Question,s:StatusLine,S:StatusLineNC,c:VertSplit,t:Title,v:Visual,V:VisualNOS,w:WarningMsg,W:WildMenu,f:Folded,F:FoldColumn,A:DiffAdd,C:DiffChange,D:DiffDelete,T:DiffText,>:SignColumn,-:Conceal,B:SpellBad,P:SpellCap,R:SpellRare,L:SpellLocal,+:Pmenu,=:PmenuSel,[:PmenuKind,]:PmenuKindSel,{:PmenuExtra,}:PmenuExtraSel,x:PmenuSbar,X:PmenuThumb,*:TabLine,#:TabLineSel,_:TabLineFill,!:CursorColumn,.:CursorLine,o:ColorColumn,q:QuickFixLine,z:StatusLineTerm,Z:StatusLineTermNC,g:MsgArea"
+# define HIGHLIGHT_INIT "8:SpecialKey,~:EndOfBuffer,@:NonText,d:Directory,e:ErrorMsg,i:IncSearch,l:Search,y:CurSearch,m:MoreMsg,M:ModeMsg,n:LineNr,a:LineNrAbove,b:LineNrBelow,N:CursorLineNr,G:CursorLineSign,O:CursorLineFold,r:Question,s:StatusLine,S:StatusLineNC,c:VertSplit,t:Title,v:Visual,V:VisualNOS,w:WarningMsg,W:WildMenu,f:Folded,F:FoldColumn,A:DiffAdd,C:DiffChange,D:DiffDelete,T:DiffText,>:SignColumn,-:Conceal,B:SpellBad,P:SpellCap,R:SpellRare,L:SpellLocal,+:Pmenu,=:PmenuSel,k:PmenuMatch,<:PmenuMatchSel,[:PmenuKind,]:PmenuKindSel,{:PmenuExtra,}:PmenuExtraSel,x:PmenuSbar,X:PmenuThumb,*:TabLine,#:TabLineSel,_:TabLineFill,!:CursorColumn,.:CursorLine,o:ColorColumn,q:QuickFixLine,z:StatusLineTerm,Z:StatusLineTermNC,g:MsgArea"
 
 // Default python version for pyx* commands
 #if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3)
index 01b6ab1e95b14c6f7a30cd75d8b4853a63983643..00b0006181a41dc9ae7d174c89233b80b5ab156c 100644 (file)
@@ -416,6 +416,88 @@ pum_under_menu(int row, int col, int only_redrawing)
            && col < pum_col + pum_width + pum_scrollbar;
 }
 
+/*
+ * displays text on the popup menu with specific attributes.
+ */
+    static void
+pum_screen_put_with_attr(int row, int col, char_u *text, int textlen, int attr)
+{
+    int                i;
+    int                leader_len;
+    int                char_len;
+    int                cells;
+    int                new_attr;
+    char_u     *rt_leader = NULL;
+    char_u     *match_leader = NULL;
+    char_u     *ptr = text;
+    garray_T   *ga = NULL;
+    char_u     *leader = ins_compl_leader();
+    int                in_fuzzy = (get_cot_flags() & COT_FUZZY) != 0;
+
+    if ((highlight_attr[HLF_PMSI] == highlight_attr[HLF_PSI] &&
+         highlight_attr[HLF_PMNI] == highlight_attr[HLF_PNI]))
+    {
+        screen_puts_len(text, textlen, row, col, attr);
+        return;
+    }
+
+#ifdef FEAT_RIGHTLEFT
+    if (leader != NULL && curwin->w_p_rl)
+        rt_leader = reverse_text(leader);
+#endif
+    match_leader = rt_leader != NULL ? rt_leader : leader;
+    leader_len = match_leader ? (int)STRLEN(match_leader) : 0;
+
+    if (match_leader != NULL && leader_len > 0 && in_fuzzy)
+        ga = fuzzy_match_str_with_pos(text, match_leader);
+
+    // Render text with proper attributes
+    while (*ptr != NUL && ptr < text + textlen)
+    {
+        char_len = mb_ptr2len(ptr);
+        cells = mb_ptr2cells(ptr);
+        new_attr = attr;
+
+        if (ga != NULL)
+        {
+            // Handle fuzzy matching
+            for (i = 0; i < ga->ga_len; i++)
+            {
+                int *match_pos = ((int *)ga->ga_data) + i;
+                int actual_char_pos = 0;
+                char_u *temp_ptr = text;
+                while (temp_ptr < ptr)
+                {
+                    temp_ptr += mb_ptr2len(temp_ptr);
+                    actual_char_pos++;
+                }
+                if (actual_char_pos == match_pos[0])
+                {
+                    new_attr = highlight_attr[(attr == highlight_attr[HLF_PSI]
+                                                       ? HLF_PMSI : HLF_PMNI)];
+                    break;
+                }
+            }
+        }
+        else if (!in_fuzzy && (ptr - text < leader_len) &&
+                               (STRNCMP(text, match_leader, leader_len) == 0))
+                new_attr = highlight_attr[(attr == highlight_attr[HLF_PSI]
+                                                   ? HLF_PMSI : HLF_PMNI)];
+
+        screen_puts_len(ptr, char_len, row, col, new_attr);
+        col += cells;
+        ptr += char_len;
+    }
+
+    if (ga != NULL)
+    {
+        ga_clear(ga);
+        vim_free(ga);
+    }
+    if (rt_leader)
+        vim_free(rt_leader);
+}
+
 /*
  * Redraw the popup menu, using "pum_first" and "pum_selected".
  */
@@ -567,8 +649,7 @@ pum_redraw(void)
                                            size++;
                                        }
                                    }
-                                   screen_puts_len(rt, (int)STRLEN(rt),
-                                                  row, col - size + 1, attr);
+                                   pum_screen_put_with_attr(row, col -size + 1, rt, (int)STRLEN(rt), attr);
                                    vim_free(rt_start);
                                }
                                vim_free(st);
@@ -596,7 +677,7 @@ pum_redraw(void)
                                    else
                                        --cells;
                                }
-                               screen_puts_len(st, size, row, col, attr);
+                               pum_screen_put_with_attr(row, col, st, size, attr);
                                vim_free(st);
                            }
                            col += width;
index 6b34c0fe150c436bbe19a792df642124e86c68e6..dbd5ef7efa67f488c561e0e3eeed38a99217127f 100644 (file)
@@ -30,6 +30,7 @@ int ins_compl_long_shown_match(void);
 unsigned int get_cot_flags(void);
 int pum_wanted(void);
 void ins_compl_show_pum(void);
+char_u *ins_compl_leader(void);
 char_u *find_word_start(char_u *ptr);
 char_u *find_word_end(char_u *ptr);
 void ins_compl_clear(void);
index d9cb16aa84d48b257e5a03396a068600fcf5c969..08526c80f24eaa23338dd1a0c262d50b4ef5e9a5 100644 (file)
@@ -40,6 +40,7 @@ int fuzzy_match(char_u *str, char_u *pat_arg, int matchseq, int *outScore, int_u
 void f_matchfuzzy(typval_T *argvars, typval_T *rettv);
 void f_matchfuzzypos(typval_T *argvars, typval_T *rettv);
 int fuzzy_match_str(char_u *str, char_u *pat);
+garray_T *fuzzy_match_str_with_pos(char_u *str, char_u *pat);
 void fuzmatch_str_free(fuzmatch_str_T *fuzmatch, int count);
 int fuzzymatches_to_strmatches(fuzmatch_str_T *fuzmatch, char_u ***matches, int count, int funcsort);
 /* vim: set ft=c : */
index 43c40e03d5444dc268b66cf376e3554898292478..864bfe3b801d195ebc317091df56ece5c6553d08 100644 (file)
@@ -5091,6 +5091,125 @@ fuzzy_match_str(char_u *str, char_u *pat)
     return score;
 }
 
+/*
+ * Fuzzy match the position of string 'pat' in string 'str'.
+ * Returns a dynamic array of matching positions. If there is no match,
+ * returns NULL.
+ */
+    garray_T *
+fuzzy_match_str_with_pos(char_u *str UNUSED, char_u *pat UNUSED)
+{
+#ifdef FEAT_SEARCH_EXTRA
+    int                    score = 0;
+    garray_T       *match_positions = ALLOC_ONE(garray_T);
+    typval_T       tv_str;
+    list_T         *l = NULL;
+    list_T         *retlist = NULL;
+    list_T         *match_str_list = NULL;
+    list_T         *match_pos_list = NULL;
+    list_T         *match_score_list = NULL;
+    listitem_T     *score_item = NULL;
+    listitem_T     *positions_item = NULL;
+    list_T         *positions_outer_list = NULL;
+    listitem_T     *outer_li = NULL;
+    list_T         *positions_inner_list = NULL;
+
+    if (match_positions == NULL)
+        return NULL;
+    ga_init2(match_positions, sizeof(int), 10);
+    if (str == NULL || pat == NULL)
+    {
+        ga_clear(match_positions);
+        return NULL;
+    }
+    l = list_alloc();
+    if (l == NULL)
+    {
+        ga_clear(match_positions);
+        return NULL;
+    }
+
+    tv_str.v_type = VAR_STRING;
+    tv_str.vval.v_string = vim_strsave(str);
+    if (tv_str.vval.v_string == NULL || list_append_tv(l, &tv_str) == FAIL)
+        goto cleanup;
+
+    retlist = list_alloc();
+    if (retlist == NULL)
+        goto cleanup;
+
+    match_str_list = list_alloc();
+    match_pos_list = list_alloc();
+    match_score_list = list_alloc();
+    if (match_str_list == NULL || match_pos_list == NULL || match_score_list == NULL)
+        goto cleanup;
+
+    list_append_list(retlist, match_str_list);
+    list_append_list(retlist, match_pos_list);
+    list_append_list(retlist, match_score_list);
+
+    fuzzy_match_in_list(l, pat, FALSE, NULL, NULL, TRUE, retlist, 1);
+
+    if (retlist->lv_len != 3)
+        goto cleanup;
+
+    score_item = list_find(retlist, 2);
+    if (score_item != NULL && score_item->li_tv.v_type == VAR_LIST)
+    {
+        list_T *score_list = score_item->li_tv.vval.v_list;
+        if (score_list->lv_len > 0)
+        {
+            listitem_T *first_score_item = score_list->lv_first;
+            if (first_score_item != NULL && first_score_item->li_tv.v_type == VAR_NUMBER)
+                score = first_score_item->li_tv.vval.v_number;
+        }
+    }
+    if (score == 0)
+        goto cleanup;
+
+    positions_item = list_find(retlist, 1);
+    if (positions_item != NULL && positions_item->li_tv.v_type == VAR_LIST)
+    {
+        positions_outer_list = positions_item->li_tv.vval.v_list;
+        if (positions_outer_list->lv_len > 0)
+        {
+            outer_li = positions_outer_list->lv_first;
+            if (outer_li != NULL && outer_li->li_tv.v_type == VAR_LIST)
+            {
+                positions_inner_list = outer_li->li_tv.vval.v_list;
+                for (listitem_T *li = positions_inner_list->lv_first; li != NULL; li = li->li_next)
+                {
+                    if (li->li_tv.v_type == VAR_NUMBER)
+                    {
+                        int pos = li->li_tv.vval.v_number;
+                        ga_grow(match_positions, 1);
+                        ((int *)match_positions->ga_data)[match_positions->ga_len] = pos;
+                        match_positions->ga_len++;
+                    }
+                }
+            }
+        }
+    }
+
+    vim_free(tv_str.vval.v_string);
+    list_free(retlist);
+    list_free(l);
+    return match_positions;
+
+cleanup:
+    vim_free(tv_str.vval.v_string);
+    list_free(match_str_list);
+    list_free(match_pos_list);
+    list_free(match_score_list);
+    list_free(retlist);
+    list_free(l);
+    ga_clear(match_positions);
+    return NULL;
+#else
+    return NULL;
+#endif
+}
+
 /*
  * Free an array of fuzzy string matches "fuzmatch[count]".
  */
diff --git a/src/testdir/dumps/Test_pum_highlights_03.dump b/src/testdir/dumps/Test_pum_highlights_03.dump
new file mode 100644 (file)
index 0000000..259e498
--- /dev/null
@@ -0,0 +1,20 @@
+|f+0&#ffffff0|o> @72
+|f+0#00e0e07#ffd7ff255|o|o+0#0000001#e0e0e08| @11| +0#4040ff13#ffffff0@59
+|f+0#0000e05#ffd7ff255|o|o+0#0000001&|b|a|r| @8| +0#4040ff13#ffffff0@59
+|f+0#0000e05#ffd7ff255|o|o+0#0000001&|B|a|z| @8| +0#4040ff13#ffffff0@59
+|f+0#0000e05#ffd7ff255|o|o+0#0000001&|b|a|l|a| @7| +0#4040ff13#ffffff0@59
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|-+2#0000000&@1| |O|m|n|i| |c|o|m|p|l|e|t|i|o|n| |(|^|O|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |1| |o|f| |8| +0#0000000&@34
diff --git a/src/testdir/dumps/Test_pum_highlights_04.dump b/src/testdir/dumps/Test_pum_highlights_04.dump
new file mode 100644 (file)
index 0000000..2204dbd
--- /dev/null
@@ -0,0 +1,20 @@
+|你*0&#ffffff0> +&@72
+|你*0#00e0e07#ffd7ff255|好*0#0000001#e0e0e08| +&@10| +0#4040ff13#ffffff0@59
+|你*0#0000e05#ffd7ff255|好*0#0000001&|吗| +&@8| +0#4040ff13#ffffff0@59
+|你*0#0000e05#ffd7ff255|不*0#0000001&|好|吗| +&@6| +0#4040ff13#ffffff0@59
+|你*0#0000e05#ffd7ff255|可*0#0000001&|好|吗| +&@6| +0#4040ff13#ffffff0@59
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|-+2#0000000&@1| |O|m|n|i| |c|o|m|p|l|e|t|i|o|n| |(|^|O|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |1| |o|f| |8| +0#0000000&@34
diff --git a/src/testdir/dumps/Test_pum_highlights_05.dump b/src/testdir/dumps/Test_pum_highlights_05.dump
new file mode 100644 (file)
index 0000000..b67c249
--- /dev/null
@@ -0,0 +1,20 @@
+|你*0&#ffffff0|吗> +&@70
+|你*0#00e0e07#ffd7ff255|好*0#0000001#e0e0e08|吗*0#00e0e07#ffd7ff255| +0#0000001#e0e0e08@8| +0#4040ff13#ffffff0@59
+|你*0#0000e05#ffd7ff255|不*0#0000001&|好|吗*0#0000e05&| +0#0000001&@6| +0#4040ff13#ffffff0@59
+|你*0#0000e05#ffd7ff255|可*0#0000001&|好|吗*0#0000e05&| +0#0000001&@6| +0#4040ff13#ffffff0@59
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|-+2#0000000&@1| |O|m|n|i| |c|o|m|p|l|e|t|i|o|n| |(|^|O|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |1| |o|f| |8| +0#0000000&@34
diff --git a/src/testdir/dumps/Test_pum_highlights_06.dump b/src/testdir/dumps/Test_pum_highlights_06.dump
new file mode 100644 (file)
index 0000000..cb9ca42
--- /dev/null
@@ -0,0 +1,20 @@
+| +0&#ffffff0@70|o>f|o|f
+| +0#4040ff13&@59| +0#0000001#e0e0e08@11|o|o+0#00e0e07#ffd7ff255|f
+| +0#4040ff13#ffffff0@59| +0#0000001#ffd7ff255@8|r|a|b|o|o+0#0000e05&|f
+| +0#4040ff13#ffffff0@59| +0#0000001#ffd7ff255@8|z|a|B|o|o+0#0000e05&|f
+| +0#4040ff13#ffffff0@59| +0#0000001#ffd7ff255@7|a|l|a|b|o|o+0#0000e05&|f
+| +0#4040ff13#ffffff0@73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+| @73|~
+|-+2#0000000&@1| |O|m|n|i| |c|o|m|p|l|e|t|i|o|n| |(|^|O|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |1| |o|f| |8| +0#0000000&@34
diff --git a/src/testdir/dumps/Test_pum_highlights_07.dump b/src/testdir/dumps/Test_pum_highlights_07.dump
new file mode 100644 (file)
index 0000000..259e498
--- /dev/null
@@ -0,0 +1,20 @@
+|f+0&#ffffff0|o> @72
+|f+0#00e0e07#ffd7ff255|o|o+0#0000001#e0e0e08| @11| +0#4040ff13#ffffff0@59
+|f+0#0000e05#ffd7ff255|o|o+0#0000001&|b|a|r| @8| +0#4040ff13#ffffff0@59
+|f+0#0000e05#ffd7ff255|o|o+0#0000001&|B|a|z| @8| +0#4040ff13#ffffff0@59
+|f+0#0000e05#ffd7ff255|o|o+0#0000001&|b|a|l|a| @7| +0#4040ff13#ffffff0@59
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|-+2#0000000&@1| |O|m|n|i| |c|o|m|p|l|e|t|i|o|n| |(|^|O|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |1| |o|f| |8| +0#0000000&@34
index 1142efc7b79180f493880ca6e0965334c9b6ddd3..86262887bb360f0d1bab143f14628a2814a12ec8 100644 (file)
@@ -1341,4 +1341,71 @@ func Test_pum_highlights_custom()
   call StopVimInTerminal(buf)
 endfunc
 
+" Test match relate highlight group in pmenu
+func Test_pum_highlights_match()
+  CheckScreendump
+  let lines =<< trim END
+    func Omni_test(findstart, base)
+      if a:findstart
+        return col(".")
+      endif
+      return {
+            \ 'words': [
+            \ { 'word': 'foo',},
+            \ { 'word': 'foobar',},
+            \ { 'word': 'fooBaz',},
+            \ { 'word': 'foobala',},
+            \ { 'word': '你好',},
+            \ { 'word': '你好吗',},
+            \ { 'word': '你不好吗',},
+            \ { 'word': '你可好吗',},
+            \]}
+    endfunc
+    set omnifunc=Omni_test
+    set completeopt=menu,noinsert,fuzzy
+    hi PmenuMatchSel  ctermfg=6 ctermbg=225
+    hi PmenuMatch     ctermfg=4 ctermbg=225
+  END
+  call writefile(lines, 'Xscript', 'D')
+  let  buf = RunVimInTerminal('-S Xscript', {})
+  call TermWait(buf)
+  call term_sendkeys(buf, "i\<C-X>\<C-O>")
+  call TermWait(buf, 50)
+  call term_sendkeys(buf, "fo")
+  call TermWait(buf, 50)
+  call VerifyScreenDump(buf, 'Test_pum_highlights_03', {})
+  call term_sendkeys(buf, "\<ESC>S\<C-x>\<C-O>")
+  call TermWait(buf, 50)
+  call term_sendkeys(buf, "你")
+  call TermWait(buf, 50)
+  call VerifyScreenDump(buf, 'Test_pum_highlights_04', {})
+  call term_sendkeys(buf, "吗")
+  call TermWait(buf, 50)
+  call VerifyScreenDump(buf, 'Test_pum_highlights_05', {})
+
+  if has('rightleft')
+    call term_sendkeys(buf, "\<C-E>\<ESC>u:set rightleft\<CR>")
+    call TermWait(buf, 50)
+    call term_sendkeys(buf, "i\<C-X>\<C-O>")
+    call TermWait(buf, 50)
+    call term_sendkeys(buf, "fo")
+    call TermWait(buf, 50)
+    call VerifyScreenDump(buf, 'Test_pum_highlights_06', {})
+    call term_sendkeys(buf, "\<C-E>\<ESC>u:set norightleft\<CR>")
+    call TermWait(buf)
+  endif
+
+  call term_sendkeys(buf, ":set completeopt-=fuzzy\<CR>")
+  call TermWait(buf)
+  call term_sendkeys(buf, "\<ESC>S\<C-x>\<C-O>")
+  call TermWait(buf, 50)
+  call term_sendkeys(buf, "fo")
+  call TermWait(buf, 50)
+  call VerifyScreenDump(buf, 'Test_pum_highlights_07', {})
+
+  call term_sendkeys(buf, "\<C-E>\<Esc>u")
+  call TermWait(buf)
+  call StopVimInTerminal(buf)
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
index 8d8e7f59fd6cb3b9dc40bc4c262231137b29655d..12dc57596c1c460a4166ab1c4f028774d1394769 100644 (file)
@@ -704,6 +704,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    476,
 /**/
     475,
 /**/
index 654e52344d883a8125aefb82b251a367102d0420..e703239371476a82625853f109cca566aa170914 100644 (file)
--- a/src/vim.h
+++ b/src/vim.h
@@ -1500,6 +1500,8 @@ typedef enum
     , HLF_SPL      // SpellLocal
     , HLF_PNI      // popup menu normal item
     , HLF_PSI      // popup menu selected item
+    , HLF_PMNI     // popup menu matched text in normal item
+    , HLF_PMSI     // popup menu matched text in selected item
     , HLF_PNK      // popup menu normal item "kind"
     , HLF_PSK      // popup menu selected item "kind"
     , HLF_PNX      // popup menu normal item "menu" (extra text)
@@ -1525,7 +1527,7 @@ typedef enum
                  'n', 'a', 'b', 'N', 'G', 'O', 'r', 's', 'S', 'c', 't', 'v', 'V', \
                  'w', 'W', 'f', 'F', 'A', 'C', 'D', 'T', '-', '>', \
                  'B', 'P', 'R', 'L', \
-                 '+', '=', '[', ']', '{', '}', 'x', 'X', \
+                 '+', '=', 'k', '<','[', ']', '{', '}', 'x', 'X', \
                  '*', '#', '_', '!', '.', 'o', 'q', \
                  'z', 'Z', 'g'}