From: glepnir Date: Mon, 16 Dec 2024 20:56:16 +0000 (+0100) Subject: patch 9.1.0936: cannot highlight completed text X-Git-Tag: v9.1.0936^0 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6a38aff218f5b99a1aed7edaa357df24b9092734;p=thirdparty%2Fvim.git 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 Signed-off-by: Christian Brabandt --- diff --git a/runtime/doc/fold.txt b/runtime/doc/fold.txt index 61f3b67f39..cf9208936f 100644 --- a/runtime/doc/fold.txt +++ b/runtime/doc/fold.txt @@ -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 diff --git a/runtime/doc/syntax.txt b/runtime/doc/syntax.txt index eb6c3b2336..7640ee1838 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 @@ 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 diff --git a/runtime/doc/tags b/runtime/doc/tags index a8b49878a3..56004e9c63 100644 --- a/runtime/doc/tags +++ b/runtime/doc/tags @@ -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* diff --git a/runtime/doc/todo.txt b/runtime/doc/todo.txt index b1318cf9e1..342332ec29 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 @@ 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) diff --git a/runtime/doc/version9.txt b/runtime/doc/version9.txt index bcda3d00de..8993e3c666 100644 --- a/runtime/doc/version9.txt +++ b/runtime/doc/version9.txt @@ -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 diff --git a/src/Makefile b/src/Makefile index f3adaeca61..b677ebc3c3 100644 --- a/src/Makefile +++ b/src/Makefile @@ -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 diff --git a/src/drawline.c b/src/drawline.c index b49e653133..ec9133103d 100644 --- a/src/drawline.c +++ b/src/drawline.c @@ -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) diff --git a/src/highlight.c b/src/highlight.c index 1a4c76d943..a4b2d48d22 100644 --- a/src/highlight.c +++ b/src/highlight.c @@ -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 }; diff --git a/src/insexpand.c b/src/insexpand.c index d3a6300a35..700ed5478f 100644 --- a/src/insexpand.c +++ b/src/insexpand.c @@ -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; diff --git a/src/proto/insexpand.pro b/src/proto/insexpand.pro index 4feab85854..2e769b89f8 100644 --- a/src/proto/insexpand.pro +++ b/src/proto/insexpand.pro @@ -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 index 0000000000..efaa1eb0cf --- /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 0000000000..a3d9be31ce --- /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 0000000000..d1686b7e00 --- /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 0000000000..0a324ef170 --- /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 0000000000..a799fcd756 --- /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 69228e1cfb..bd369574f1 100644 --- a/src/testdir/test_popup.vim +++ b/src/testdir/test_popup.vim @@ -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\\") + call VerifyScreenDump(buf, 'Test_pum_matchins_01', {}) + call term_sendkeys(buf, "\\") + + call TermWait(buf) + call term_sendkeys(buf, "S\\\") + call VerifyScreenDump(buf, 'Test_pum_matchins_02', {}) + call term_sendkeys(buf, "\\") + + call TermWait(buf) + call term_sendkeys(buf, "S\\\\") + call VerifyScreenDump(buf, 'Test_pum_matchins_03', {}) + call term_sendkeys(buf, "\\") + + " restore after accept + call TermWait(buf) + call term_sendkeys(buf, "S\\\") + call VerifyScreenDump(buf, 'Test_pum_matchins_04', {}) + call term_sendkeys(buf, "\\") + + " restore after cancel completion + call TermWait(buf) + call term_sendkeys(buf, "S\\\") + call VerifyScreenDump(buf, 'Test_pum_matchins_05', {}) + call term_sendkeys(buf, "\\") + + call StopVimInTerminal(buf) +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/version.c b/src/version.c index a5db0d490c..eb37def787 100644 --- a/src/version.c +++ b/src/version.c @@ -704,6 +704,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 936, /**/ 935, /**/