changeset 26334:baec4e1cee43 v8.2.3698

patch 8.2.3698: match highlighting continues over breakindent Commit: https://github.com/vim/vim/commit/0c359af5c0fd106d3f57cc0bb7cef1c89b5e1e10 Author: Bram Moolenaar <Bram@vim.org> Date: Mon Nov 29 19:18:57 2021 +0000 patch 8.2.3698: match highlighting continues over breakindent Problem: Match highlighting continues over breakindent. Solution: Stop before the end column. (closes https://github.com/vim/vim/issues/9242)
author Bram Moolenaar <Bram@vim.org>
date Mon, 29 Nov 2021 20:30:04 +0100
parents ecabeda57f71
children c12a888d1f63
files src/drawline.c src/match.c src/proto/match.pro src/testdir/dumps/Test_match_linebreak.dump src/testdir/test_match.vim src/version.c
diffstat 6 files changed, 44 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/drawline.c
+++ b/src/drawline.c
@@ -434,6 +434,7 @@ win_line(
 
 #if defined(FEAT_CONCEAL) || defined(FEAT_SEARCH_EXTRA)
     int		match_conc	= 0;	// cchar for match functions
+    int		on_last_col     = FALSE;
 #endif
 #ifdef FEAT_CONCEAL
     int		syntax_flags	= 0;
@@ -1382,7 +1383,8 @@ win_line(
 		v = (long)(ptr - line);
 		search_attr = update_search_hl(wp, lnum, (colnr_T)v, &line,
 				      &screen_search_hl, &has_match_conc,
-				      &match_conc, did_line_attr, lcs_eol_one);
+				      &match_conc, did_line_attr, lcs_eol_one,
+				      &on_last_col);
 		ptr = line + v;  // "line" may have been changed
 
 		// Do not allow a conceal over EOL otherwise EOL will be missed
@@ -2012,6 +2014,10 @@ win_line(
 			if (n_extra < 0)
 			    n_extra = 0;
 		    }
+		    if (on_last_col)
+			// Do not continue search/match highlighting over the
+			// line break.
+			search_attr = 0;
 
 		    if (c == TAB && n_extra + col > wp->w_width)
 # ifdef FEAT_VARTABS
--- a/src/match.c
+++ b/src/match.c
@@ -703,6 +703,8 @@ prepare_search_hl_line(
  * After end, check for start/end of next match.
  * When another match, have to check for start again.
  * Watch out for matching an empty string!
+ * "on_last_col" is set to TRUE with non-zero search_attr and the next column
+ * is endcol.
  * Return the updated search_attr.
  */
     int
@@ -715,7 +717,8 @@ update_search_hl(
 	int	    *has_match_conc UNUSED,
 	int	    *match_conc UNUSED,
 	int	    did_line_attr,
-	int	    lcs_eol_one)
+	int	    lcs_eol_one,
+	int	    *on_last_col)
 {
     matchitem_T *cur;		    // points to the match list
     match_T	*shl;		    // points to search_hl or a match
@@ -832,7 +835,10 @@ update_search_hl(
 	else
 	    shl = &cur->hl;
 	if (shl->attr_cur != 0)
+	{
 	    search_attr = shl->attr_cur;
+	    *on_last_col = col + 1 >= shl->endcol;
+	}
 	if (shl != search_hl && cur != NULL)
 	    cur = cur->next;
     }
--- a/src/proto/match.pro
+++ b/src/proto/match.pro
@@ -3,7 +3,7 @@ void clear_matches(win_T *wp);
 void init_search_hl(win_T *wp, match_T *search_hl);
 void prepare_search_hl(win_T *wp, match_T *search_hl, linenr_T lnum);
 int prepare_search_hl_line(win_T *wp, linenr_T lnum, colnr_T mincol, char_u **line, match_T *search_hl, int *search_attr);
-int update_search_hl(win_T *wp, linenr_T lnum, colnr_T col, char_u **line, match_T *search_hl, int *has_match_conc, int *match_conc, int did_line_attr, int lcs_eol_one);
+int update_search_hl(win_T *wp, linenr_T lnum, colnr_T col, char_u **line, match_T *search_hl, int *has_match_conc, int *match_conc, int did_line_attr, int lcs_eol_one, int *on_last_col);
 int get_prevcol_hl_flag(win_T *wp, match_T *search_hl, long curcol);
 void get_search_match_hl(win_T *wp, match_T *search_hl, long col, int *char_attr);
 void f_clearmatches(typval_T *argvars, typval_T *rettv);
new file mode 100644
--- /dev/null
+++ b/src/testdir/dumps/Test_match_linebreak.dump
@@ -0,0 +1,10 @@
+>x+0&#ffffff0@49|]+0#ffffff16#e000002| +0#0000000#ffffff0@23
+|x@69| @4
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+| +0#0000000&@56|1|,|1| @10|A|l@1| 
--- a/src/testdir/test_match.vim
+++ b/src/testdir/test_match.vim
@@ -349,6 +349,23 @@ func Test_matchadd_other_window()
   call delete('XscriptMatchCommon')
 endfunc
 
+func Test_match_in_linebreak()
+  CheckRunVimInTerminal
+
+  let lines =<< trim END
+    set breakindent linebreak breakat+=]
+    call printf('%s]%s', repeat('x', 50), repeat('x', 70))->setline(1)
+    call matchaddpos('ErrorMsg', [[1, 51]])
+  END
+  call writefile(lines, 'XscriptMatchLinebreak')
+  let buf = RunVimInTerminal('-S XscriptMatchLinebreak', #{rows: 10})
+  call TermWait(buf)
+  call VerifyScreenDump(buf, 'Test_match_linebreak', {})
+
+  call StopVimInTerminal(buf)
+  call delete('XscriptMatchLinebreak')
+endfunc
+
 " Test for deleting matches outside of the screen redraw top/bottom lines
 " This should cause a redraw of those lines.
 func Test_matchdelete_redraw()
--- a/src/version.c
+++ b/src/version.c
@@ -758,6 +758,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    3698,
+/**/
     3697,
 /**/
     3696,