patch 9.1.0936: cannot highlight completed text
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>
diff --git a/runtime/doc/fold.txt b/runtime/doc/fold.txt
index 61f3b67..cf92089 100644
--- a/runtime/doc/fold.txt
+++ b/runtime/doc/fold.txt
@@ -160,7 +160,7 @@
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
diff --git a/runtime/doc/syntax.txt b/runtime/doc/syntax.txt
index eb6c3b2..7640ee1 100644
--- a/runtime/doc/syntax.txt
+++ b/runtime/doc/syntax.txt
@@ -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 @@
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
diff --git a/runtime/doc/tags b/runtime/doc/tags
index a8b4987..56004e9 100644
--- a/runtime/doc/tags
+++ b/runtime/doc/tags
@@ -8136,6 +8136,7 @@
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*
diff --git a/runtime/doc/todo.txt b/runtime/doc/todo.txt
index b1318cf..342332e 100644
--- a/runtime/doc/todo.txt
+++ b/runtime/doc/todo.txt
@@ -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 @@
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)
diff --git a/runtime/doc/version9.txt b/runtime/doc/version9.txt
index bcda3d0..8993e3c 100644
--- a/runtime/doc/version9.txt
+++ b/runtime/doc/version9.txt
@@ -41653,6 +41653,7 @@
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
diff --git a/src/Makefile b/src/Makefile
index f3adaec..b677ebc 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -359,7 +359,7 @@
#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
diff --git a/src/drawline.c b/src/drawline.c
index b49e653..ec91331 100644
--- a/src/drawline.c
+++ b/src/drawline.c
@@ -1139,6 +1139,7 @@
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 @@
// 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 @@
}
// 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 @@
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)
diff --git a/src/highlight.c b/src/highlight.c
index 1a4c76d..a4b2d48 100644
--- a/src/highlight.c
+++ b/src/highlight.c
@@ -262,6 +262,7 @@
"default link PmenuMatchSel PmenuSel",
"default link PmenuExtra Pmenu",
"default link PmenuExtraSel PmenuSel",
+ "default link ComplMatchIns Normal",
CENT("Normal cterm=NONE", "Normal gui=NONE"),
NULL
};
diff --git a/src/insexpand.c b/src/insexpand.c
index d3a6300..700ed54 100644
--- a/src/insexpand.c
+++ b/src/insexpand.c
@@ -173,6 +173,7 @@
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_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);
@@ -898,6 +904,32 @@
}
/*
+ * 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".
*/
static void
@@ -917,7 +949,7 @@
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 @@
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 @@
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 @@
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_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 @@
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 @@
// 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 @@
// 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 @@
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;
diff --git a/src/proto/insexpand.pro b/src/proto/insexpand.pro
index 4feab85..2e769b8 100644
--- a/src/proto/insexpand.pro
+++ b/src/proto/insexpand.pro
@@ -60,5 +60,6 @@
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
index 0000000..efaa1eb
--- /dev/null
+++ b/src/testdir/dumps/Test_pum_matchins_01.dump
@@ -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
index 0000000..a3d9be3
--- /dev/null
+++ b/src/testdir/dumps/Test_pum_matchins_02.dump
@@ -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
index 0000000..d1686b7
--- /dev/null
+++ b/src/testdir/dumps/Test_pum_matchins_03.dump
@@ -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
index 0000000..0a324ef
--- /dev/null
+++ b/src/testdir/dumps/Test_pum_matchins_04.dump
@@ -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
index 0000000..a799fcd
--- /dev/null
+++ b/src/testdir/dumps/Test_pum_matchins_05.dump
@@ -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|
diff --git a/src/testdir/test_popup.vim b/src/testdir/test_popup.vim
index 69228e1..bd36957 100644
--- a/src/testdir/test_popup.vim
+++ b/src/testdir/test_popup.vim
@@ -1712,4 +1712,49 @@
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
diff --git a/src/version.c b/src/version.c
index a5db0d4..eb37def 100644
--- a/src/version.c
+++ b/src/version.c
@@ -705,6 +705,8 @@
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 936,
+/**/
935,
/**/
934,