# HG changeset patch # User Bram Moolenaar # Date 1638214204 -3600 # Node ID baec4e1cee43128ed1a81b9b20d3b10ed1e01714 # Parent ecabeda57f71f6d2a1ad2e501a6805803fab6188 patch 8.2.3698: match highlighting continues over breakindent Commit: https://github.com/vim/vim/commit/0c359af5c0fd106d3f57cc0bb7cef1c89b5e1e10 Author: Bram Moolenaar 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) diff --git a/src/drawline.c b/src/drawline.c --- 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 diff --git a/src/match.c b/src/match.c --- 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; } diff --git a/src/proto/match.pro b/src/proto/match.pro --- 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); diff --git a/src/testdir/dumps/Test_match_linebreak.dump b/src/testdir/dumps/Test_match_linebreak.dump 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| diff --git a/src/testdir/test_match.vim b/src/testdir/test_match.vim --- 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() diff --git a/src/version.c b/src/version.c --- 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,