]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.1.0936: cannot highlight completed text v9.1.0936
authorglepnir <glephunter@gmail.com>
Mon, 16 Dec 2024 20:56:16 +0000 (21:56 +0100)
committerChristian Brabandt <cb@256bit.org>
Mon, 16 Dec 2024 20:56:16 +0000 (21:56 +0100)
Problem:  cannot highlight completed text
Solution: (optionally) highlight auto-completed text using the
          ComplMatchIns highlight group (glepnir)

closes: #16173

Signed-off-by: glepnir <glephunter@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
17 files changed:
runtime/doc/fold.txt
runtime/doc/syntax.txt
runtime/doc/tags
runtime/doc/todo.txt
runtime/doc/version9.txt
src/Makefile
src/drawline.c
src/highlight.c
src/insexpand.c
src/proto/insexpand.pro
src/testdir/dumps/Test_pum_matchins_01.dump [new file with mode: 0644]
src/testdir/dumps/Test_pum_matchins_02.dump [new file with mode: 0644]
src/testdir/dumps/Test_pum_matchins_03.dump [new file with mode: 0644]
src/testdir/dumps/Test_pum_matchins_04.dump [new file with mode: 0644]
src/testdir/dumps/Test_pum_matchins_05.dump [new file with mode: 0644]
src/testdir/test_popup.vim
src/version.c

index 61f3b67f393331de5a51d1127f87a41ea2d369ef..cf9208936f8e461948b8c7f5b110df4886590d3d 100644 (file)
@@ -160,7 +160,7 @@ lines needed for the computation of a given line: For example, try to avoid the
 fold levels on previous lines until an independent fold level is found.
 
 If this proves difficult, the next best thing could be to cache all fold levels
-in a buffer-local variable (b:foldlevels) that is only updated on |b:changedtick|: 
+in a buffer-local variable (b:foldlevels) that is only updated on |b:changedtick|:
 >vim
   vim9script
   def MyFoldFunc(): number
index eb6c3b23360fc8a5fa6e870fe1258e49c177ad86..7640ee1838a97d2782b3099bdb0b03eab931a20c 100644 (file)
@@ -1,4 +1,4 @@
-*syntax.txt*   For Vim version 9.1.  Last change: 2024 Dec 12
+*syntax.txt*   For Vim version 9.1.  Last change: 2024 Dec 16
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -5857,6 +5857,8 @@ PmenuThumb        Popup menu: Thumb of the scrollbar.
 PmenuMatch     Popup menu: Matched text in normal item.
                                                        *hl-PmenuMatchSel*
 PmenuMatchSel  Popup menu: Matched text in selected item.
+                                                       *hl-ComplMatchIns*
+ComplMatchIns  Matched text of the currently inserted completion.
                                                        *hl-PopupNotification*
 PopupNotification
                Popup window created with |popup_notification()|.  If not
index a8b49878a3d35126b06519be4b08aaa8dd2c6d7b..56004e9c63483e758eb59be9c89dcdbef0983ad4 100644 (file)
@@ -8136,6 +8136,7 @@ hit-return        message.txt     /*hit-return*
 hitest.vim     syntax.txt      /*hitest.vim*
 hjkl   usr_02.txt      /*hjkl*
 hl-ColorColumn syntax.txt      /*hl-ColorColumn*
+hl-ComplMatchIns       syntax.txt      /*hl-ComplMatchIns*
 hl-Conceal     syntax.txt      /*hl-Conceal*
 hl-CurSearch   syntax.txt      /*hl-CurSearch*
 hl-Cursor      syntax.txt      /*hl-Cursor*
index b1318cf9e139001b2a67db8c01d340d2b44af472..342332ec2917193a781a7e5f85a52b6abcb6fb6b 100644 (file)
@@ -1,4 +1,4 @@
-*todo.txt*      For Vim version 9.1.  Last change: 2024 Dec 04
+*todo.txt*      For Vim version 9.1.  Last change: 2024 Dec 16
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -1093,9 +1093,6 @@ Problem with 'delcombine'. (agguser, 2017 Nov 10, #2313)
 MS-Windows: buffer completion doesn't work when using backslash (or slash)
 for a path separator. (xtal8, #2201)
 
-Would be nice for Insert mode completion to highlight the text that was added
-(and may change when picking another completion).
-
 Test more runtime files.
 
 Window not closed when deleting buffer. (Harm te Hennepe, 2017 Aug 27, #2029)
index bcda3d00dec0682e084dc6290fa99698cf36d63e..8993e3c666791b47ba38c7e60e233d9e931db56a 100644 (file)
@@ -41653,6 +41653,7 @@ Autocommands: ~
 
 Highlighting: ~
 
+|hl-ComplMatchIns|     matched text of the currently inserted completion.
 |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
index f3adaeca61864dea220b9c00096eb3dbf362360d..b677ebc3c3cf6e5c1cef12b6ee0197409729ccbc 100644 (file)
@@ -359,7 +359,7 @@ CClink = $(CC)
 #CONF_OPT_GUI = --enable-gui=motif --with-motif-lib="-static -lXm -shared"
 
 # Uncomment this line to run an individual test with gvim.
-#GUI_TESTARG = GUI_FLAG=-g 
+#GUI_TESTARG = GUI_FLAG=-g
 
 # DARWIN - detecting Mac OS X
 # Uncomment this line when you want to compile a Unix version of Vim on
index b49e6531332f4fd40b5d63598994380be2ea7638..ec9133103d73d70329a17a7b436acaa8b322e8ad 100644 (file)
@@ -1139,6 +1139,7 @@ win_line(
     long       vcol_prev = -1;         // "wlv.vcol" of previous character
     char_u     *line;                  // current line
     char_u     *ptr;                   // current position in "line"
+    int                in_curline = wp == curwin && lnum == curwin->w_cursor.lnum;
 
 #ifdef FEAT_PROP_POPUP
     char_u     *p_extra_free2 = NULL;   // another p_extra to be freed
@@ -1172,6 +1173,7 @@ win_line(
                                        // highlighting
     int                area_attr = 0;          // attributes desired by highlighting
     int                search_attr = 0;        // attributes desired by 'hlsearch'
+    int                ins_match_attr = 0;     // attributes desired by PmenuMatch
 #ifdef FEAT_SYN_HL
     int                vcol_save_attr = 0;     // saved attr for 'cursorcolumn'
     int                syntax_attr = 0;        // attributes desired by syntax
@@ -1415,8 +1417,7 @@ win_line(
            }
 
            // Check if the character under the cursor should not be inverted
-           if (!highlight_match && lnum == curwin->w_cursor.lnum
-                                                               && wp == curwin
+           if (!highlight_match && in_curline
 #ifdef FEAT_GUI
                    && !gui.in_use
 #endif
@@ -3939,6 +3940,14 @@ win_line(
        if (wlv.draw_state == WL_LINE)
            vcol_prev = wlv.vcol;
 
+       if (wlv.draw_state == WL_LINE
+               && (State & MODE_INSERT) && in_curline && ins_compl_active())
+       {
+           ins_match_attr = ins_compl_col_range_attr(wlv.col);
+           if (ins_match_attr > 0)
+               wlv.char_attr = hl_combine_attr(wlv.char_attr, ins_match_attr);
+       }
+
        // Store character to be displayed.
        // Skip characters that are left of the screen for 'nowrap'.
        if (wlv.draw_state < WL_LINE || skip_cells <= 0)
index 1a4c76d9439e3c2bb259ecc9bd303403f4d2f209..a4b2d48d2208378e477bff29082ec100b6bb8b5d 100644 (file)
@@ -262,6 +262,7 @@ static char *(highlight_init_both[]) = {
     "default link PmenuMatchSel PmenuSel",
     "default link PmenuExtra Pmenu",
     "default link PmenuExtraSel PmenuSel",
+    "default link ComplMatchIns Normal",
     CENT("Normal cterm=NONE", "Normal gui=NONE"),
     NULL
 };
index d3a6300a3557b6eef144bc9fcec53f41139915a8..700ed5478fcc583e2400db2c237146bbb1317f4a 100644 (file)
@@ -173,6 +173,7 @@ static pos_T          compl_startpos;
 static int       compl_length = 0;
 static colnr_T   compl_col = 0;            // column where the text starts
                                            // that is being completed
+static colnr_T   compl_ins_end_col = 0;
 static string_T          compl_orig_text = {NULL, 0};  // text as it was before
                                            // completion started
 static int       compl_cont_mode = 0;
@@ -198,6 +199,11 @@ static int   compl_selected_item = -1;
 
 static int       *compl_fuzzy_scores;
 
+// "compl_match_array" points the currently displayed list of entries in the
+// popup menu.  It is NULL when there is no popup menu.
+static pumitem_T *compl_match_array = NULL;
+static int compl_match_arraysize;
+
 static int ins_compl_add(char_u *str, int len, char_u *fname, char_u **cptext, typval_T *user_data, int cdir, int flags, int adup, int *user_hl);
 static void ins_compl_longest_match(compl_T *match);
 static void ins_compl_del_pum(void);
@@ -897,6 +903,32 @@ ins_compl_equal(compl_T *match, char_u *str, int len)
     return STRNCMP(match->cp_str.string, str, (size_t)len) == 0;
 }
 
+/*
+ * when len is -1 mean use whole length of p otherwise part of p
+ */
+    static void
+ins_compl_insert_bytes(char_u *p, int len)
+{
+    if (len == -1)
+       len = (int)STRLEN(p);
+    ins_bytes_len(p, len);
+    compl_ins_end_col = curwin->w_cursor.col - 1;
+}
+
+/*
+ *  Checks if the column is within the currently inserted completion text
+ *  column range. If it is, it returns a special highlight attribute.
+ *  -1 mean normal item.
+ */
+    int
+ins_compl_col_range_attr(int col)
+{
+    if (col >= compl_col && col < compl_ins_end_col)
+       return syn_name2attr((char_u *)"ComplMatchIns");
+
+    return -1;
+}
+
 /*
  * Reduce the longest common string for match "match".
  */
@@ -917,7 +949,7 @@ ins_compl_longest_match(compl_T *match)
        compl_leader.length = match->cp_str.length;
        had_match = (curwin->w_cursor.col > compl_col);
        ins_compl_delete();
-       ins_bytes(compl_leader.string + get_compl_len());
+       ins_compl_insert_bytes(compl_leader.string + get_compl_len(), -1);
        ins_redraw(FALSE);
 
        // When the match isn't there (to avoid matching itself) remove it
@@ -967,7 +999,7 @@ ins_compl_longest_match(compl_T *match)
 
        had_match = (curwin->w_cursor.col > compl_col);
        ins_compl_delete();
-       ins_bytes(compl_leader.string + get_compl_len());
+       ins_compl_insert_bytes(compl_leader.string + get_compl_len(), -1);
        ins_redraw(FALSE);
 
        // When the match isn't there (to avoid matching itself) remove it
@@ -1060,12 +1092,6 @@ get_cot_flags(void)
     return curbuf->b_cot_flags != 0 ? curbuf->b_cot_flags : cot_flags;
 }
 
-
-// "compl_match_array" points the currently displayed list of entries in the
-// popup menu.  It is NULL when there is no popup menu.
-static pumitem_T *compl_match_array = NULL;
-static int compl_match_arraysize;
-
 /*
  * Update the screen and when there is any scrolling remove the popup menu.
  */
@@ -1817,6 +1843,7 @@ ins_compl_clear(void)
     compl_cont_status = 0;
     compl_started = FALSE;
     compl_matches = 0;
+    compl_ins_end_col = 0;
     VIM_CLEAR_STRING(compl_pattern);
     VIM_CLEAR_STRING(compl_leader);
     edit_submode_extra = NULL;
@@ -1965,7 +1992,7 @@ ins_compl_new_leader(void)
 {
     ins_compl_del_pum();
     ins_compl_delete();
-    ins_bytes(compl_leader.string + get_compl_len());
+    ins_compl_insert_bytes(compl_leader.string + get_compl_len(), -1);
     compl_used_match = FALSE;
 
     if (compl_started)
@@ -2410,7 +2437,7 @@ ins_compl_stop(int c, int prev_mode, int retval)
            int     compl_len = get_compl_len();
 
            if ((int)plen > compl_len)
-               ins_bytes_len(p + compl_len, (int)(plen - compl_len));
+               ins_compl_insert_bytes(p + compl_len, (int)(plen - compl_len));
        }
        retval = TRUE;
     }
@@ -4260,7 +4287,7 @@ ins_compl_insert(int in_compl_func)
     // Make sure we don't go over the end of the string, this can happen with
     // illegal bytes.
     if (compl_len < (int)compl_shown_match->cp_str.length)
-       ins_bytes(compl_shown_match->cp_str.string + compl_len);
+       ins_compl_insert_bytes(compl_shown_match->cp_str.string + compl_len, -1);
     if (match_at_original_text(compl_shown_match))
        compl_used_match = FALSE;
     else
@@ -4537,7 +4564,7 @@ ins_compl_next(
     // Insert the text of the new completion, or the compl_leader.
     if (compl_no_insert && !started)
     {
-       ins_bytes(compl_orig_text.string + get_compl_len());
+       ins_compl_insert_bytes(compl_orig_text.string + get_compl_len(), -1);
        compl_used_match = FALSE;
     }
     else if (insert_match)
@@ -4545,7 +4572,7 @@ ins_compl_next(
        if (!compl_get_longest || compl_used_match)
            ins_compl_insert(in_compl_func);
        else
-           ins_bytes(compl_leader.string + get_compl_len());
+           ins_compl_insert_bytes(compl_leader.string + get_compl_len(), -1);
     }
     else
        compl_used_match = FALSE;
index 4feab85854d4aee02141744bcd0e7c3a5ee951d4..2e769b89f89bb8efe6817c2f71766c9fb3c2bd0a 100644 (file)
@@ -60,5 +60,6 @@ void ins_compl_delete(void);
 void ins_compl_insert(int in_compl_func);
 void ins_compl_check_keys(int frequency, int in_compl_func);
 int ins_complete(int c, int enable_pum);
+int ins_compl_col_range_attr(int col);
 void free_insexpand_stuff(void);
 /* vim: set ft=c : */
diff --git a/src/testdir/dumps/Test_pum_matchins_01.dump b/src/testdir/dumps/Test_pum_matchins_01.dump
new file mode 100644 (file)
index 0000000..efaa1eb
--- /dev/null
@@ -0,0 +1,20 @@
+|f+0#ff404010#ffffff0|o@1> +0#0000000&@71
+|f+0#0000001#e0e0e08|o@1| @11| +0#4040ff13#ffffff0@59
+|b+0#0000001#ffd7ff255|a|r| @11| +0#4040ff13#ffffff0@59
+|你*0#0000001#ffd7ff255|好| +&@10| +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| |3| +0#0000000&@34
diff --git a/src/testdir/dumps/Test_pum_matchins_02.dump b/src/testdir/dumps/Test_pum_matchins_02.dump
new file mode 100644 (file)
index 0000000..a3d9be3
--- /dev/null
@@ -0,0 +1,20 @@
+|b+0#ff404010#ffffff0|a|r> +0#0000000&@71
+|f+0#0000001#ffd7ff255|o@1| @11| +0#4040ff13#ffffff0@59
+|b+0#0000001#e0e0e08|a|r| @11| +0#4040ff13#ffffff0@59
+|你*0#0000001#ffd7ff255|好| +&@10| +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| |2| |o|f| |3| +0#0000000&@34
diff --git a/src/testdir/dumps/Test_pum_matchins_03.dump b/src/testdir/dumps/Test_pum_matchins_03.dump
new file mode 100644 (file)
index 0000000..d1686b7
--- /dev/null
@@ -0,0 +1,20 @@
+|你*0#ff404010#ffffff0|好> +0#0000000&@70
+|f+0#0000001#ffd7ff255|o@1| @11| +0#4040ff13#ffffff0@59
+|b+0#0000001#ffd7ff255|a|r| @11| +0#4040ff13#ffffff0@59
+|你*0#0000001#e0e0e08|好| +&@10| +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| |3| |o|f| |3| +0#0000000&@34
diff --git a/src/testdir/dumps/Test_pum_matchins_04.dump b/src/testdir/dumps/Test_pum_matchins_04.dump
new file mode 100644 (file)
index 0000000..0a324ef
--- /dev/null
@@ -0,0 +1,20 @@
+|f+0&#ffffff0|o@1> @71
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|-+2#0000000&@1| |I|N|S|E|R|T| |-@1| +0&&@44|1|,|4| @10|A|l@1| 
diff --git a/src/testdir/dumps/Test_pum_matchins_05.dump b/src/testdir/dumps/Test_pum_matchins_05.dump
new file mode 100644 (file)
index 0000000..a799fcd
--- /dev/null
@@ -0,0 +1,20 @@
+|f+0&#ffffff0|o@1| > @70
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|-+2#0000000&@1| |I|N|S|E|R|T| |-@1| +0&&@44|1|,|5| @10|A|l@1| 
index 69228e1cfb7a3a4d68694df9882bfc3a5f9e1e48..bd369574f101b0201c1ea357b215948fba413f7c 100644 (file)
@@ -1712,4 +1712,49 @@ func Test_pum_keep_select()
   call StopVimInTerminal(buf)
 endfunc
 
+func Test_pum_matchins_higlight()
+  CheckScreendump
+  let lines =<< trim END
+    func Omni_test(findstart, base)
+      if a:findstart
+        return col(".")
+      endif
+      return [#{word: "foo"}, #{word: "bar"}, #{word: "你好"}]
+    endfunc
+    set omnifunc=Omni_test
+    hi ComplMatchIns ctermfg=red
+  END
+  call writefile(lines, 'Xscript', 'D')
+  let buf = RunVimInTerminal('-S Xscript', {})
+
+  call TermWait(buf)
+  call term_sendkeys(buf, "S\<C-X>\<C-O>")
+  call VerifyScreenDump(buf, 'Test_pum_matchins_01', {})
+  call term_sendkeys(buf, "\<C-E>\<Esc>")
+
+  call TermWait(buf)
+  call term_sendkeys(buf, "S\<C-X>\<C-O>\<C-N>")
+  call VerifyScreenDump(buf, 'Test_pum_matchins_02', {})
+  call term_sendkeys(buf, "\<C-E>\<Esc>")
+
+  call TermWait(buf)
+  call term_sendkeys(buf, "S\<C-X>\<C-O>\<C-N>\<C-N>")
+  call VerifyScreenDump(buf, 'Test_pum_matchins_03', {})
+  call term_sendkeys(buf, "\<C-E>\<Esc>")
+
+  " restore after accept
+  call TermWait(buf)
+  call term_sendkeys(buf, "S\<C-X>\<C-O>\<C-Y>")
+  call VerifyScreenDump(buf, 'Test_pum_matchins_04', {})
+  call term_sendkeys(buf, "\<C-E>\<Esc>")
+
+  " restore after cancel completion
+  call TermWait(buf)
+  call term_sendkeys(buf, "S\<C-X>\<C-O>\<Space>")
+  call VerifyScreenDump(buf, 'Test_pum_matchins_05', {})
+  call term_sendkeys(buf, "\<C-E>\<Esc>")
+
+  call StopVimInTerminal(buf)
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
index a5db0d490c02b064d604e9301ef8b71aaac8a860..eb37def7872ba8c74b00cd1ec7f120f00ed2f409 100644 (file)
@@ -704,6 +704,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    936,
 /**/
     935,
 /**/