Merge pull request #21173 from zeertzjq/vim-8.2.3698

vim-patch:8.2.{3698,3940,4062}: match highlight continues in linebreak
This commit is contained in:
zeertzjq 2022-11-24 19:41:02 +08:00 committed by GitHub
commit 38863f5242
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 179 additions and 5 deletions

View File

@ -618,6 +618,8 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
LineDrawState draw_state = WL_START; // what to draw next
int match_conc = 0; ///< cchar for match functions
bool on_last_col = false;
int syntax_flags = 0;
int syntax_seqnr = 0;
int prev_syntax_id = 0;
@ -627,7 +629,6 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
///< force wrapping
int vcol_off = 0; ///< offset for concealed characters
int did_wcol = false;
int match_conc = 0; ///< cchar for match functions
int old_boguscols = 0;
#define VCOL_HLC (vcol - vcol_off)
#define FIX_FOR_BOGUSCOLS \
@ -1429,8 +1430,8 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
// When another match, have to check for start again.
v = (ptr - line);
search_attr = update_search_hl(wp, lnum, (colnr_T)v, &line, &screen_search_hl,
&has_match_conc,
&match_conc, lcs_eol_one, &search_attr_from_match);
&has_match_conc, &match_conc, lcs_eol_one,
&on_last_col, &search_attr_from_match);
ptr = line + v; // "line" may have been changed
// Do not allow a conceal over EOL otherwise EOL will be missed
@ -1843,6 +1844,12 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
n_extra = 0;
}
}
if (on_last_col && c != TAB) {
// Do not continue search/match highlighting over the
// line break, but for TABs the highlighting should
// include the complete width of the character
search_attr = 0;
}
if (c == TAB && n_extra + col > grid->cols) {
n_extra = tabstop_padding((colnr_T)vcol, wp->w_buffer->b_p_ts,

View File

@ -425,7 +425,7 @@ static void next_search_hl(win_T *win, match_T *search_hl, match_T *shl, linenr_
const int called_emsg_before = called_emsg;
// for :{range}s/pat only highlight inside the range
if (lnum < search_first_line || lnum > search_last_line) {
if ((lnum < search_first_line || lnum > search_last_line) && cur == NULL) {
shl->lnum = 0;
return;
}
@ -677,9 +677,11 @@ bool prepare_search_hl_line(win_T *wp, linenr_T lnum, colnr_T mincol, char_u **l
/// 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 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 lcs_eol_one,
int *has_match_conc, int *match_conc, int lcs_eol_one, bool *on_last_col,
bool *search_attr_from_match)
{
matchitem_T *cur = wp->w_match_head; // points to the match list
@ -792,6 +794,7 @@ int update_search_hl(win_T *wp, linenr_T lnum, colnr_T col, char_u **line, match
}
if (shl->attr_cur != 0) {
search_attr = shl->attr_cur;
*on_last_col = col + 1 >= shl->endcol;
*search_attr_from_match = shl != search_hl;
}
if (shl != search_hl && cur != NULL) {

View File

@ -363,4 +363,80 @@ 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
func Test_match_with_incsearch()
CheckRunVimInTerminal
let lines =<< trim END
set incsearch
call setline(1, range(20))
call matchaddpos('ErrorMsg', [3])
END
call writefile(lines, 'XmatchWithIncsearch')
let buf = RunVimInTerminal('-S XmatchWithIncsearch', #{rows: 6})
call TermWait(buf)
call VerifyScreenDump(buf, 'Test_match_with_incsearch_1', {})
call term_sendkeys(buf, ":s/0")
call VerifyScreenDump(buf, 'Test_match_with_incsearch_2', {})
call term_sendkeys(buf, "\<CR>")
call StopVimInTerminal(buf)
call delete('XmatchWithIncsearch')
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()
new
call setline(1, range(1, 500))
call cursor(250, 1)
let m1 = matchaddpos('Search', [[250]])
let m2 = matchaddpos('Search', [[10], [450]])
redraw!
let m3 = matchaddpos('Search', [[240], [260]])
call matchdelete(m2)
let m = getmatches()
call assert_equal(2, len(m))
call assert_equal([250], m[0].pos1)
redraw!
call matchdelete(m1)
call assert_equal(1, len(getmatches()))
bw!
endfunc
func Test_match_tab_with_linebreak()
CheckRunVimInTerminal
let lines =<< trim END
set linebreak
call setline(1, "\tix")
call matchadd('ErrorMsg', '\t')
END
call writefile(lines, 'XscriptMatchTabLinebreak')
let buf = RunVimInTerminal('-S XscriptMatchTabLinebreak', #{rows: 10})
call TermWait(buf)
call VerifyScreenDump(buf, 'Test_match_tab_linebreak', {})
call StopVimInTerminal(buf)
call delete('XscriptMatchTabLinebreak')
endfunc
" vim: shiftwidth=2 sts=2 expandtab

View File

@ -2,6 +2,7 @@ local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local clear = helpers.clear
local exec = helpers.exec
local feed = helpers.feed
before_each(clear)
@ -36,3 +37,90 @@ describe('matchaddpos()', function()
]])
end)
end)
describe('match highlighting', function()
-- oldtest: Test_match_in_linebreak()
it('does not continue in linebreak vim-patch:8.2.3698', function()
local screen = Screen.new(75, 10)
screen:set_default_attr_ids({
[0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText
[1] = {background = Screen.colors.Red, foreground = Screen.colors.White}, -- ErrorMsg
})
screen:attach()
exec([=[
set breakindent linebreak breakat+=]
call printf('%s]%s', repeat('x', 50), repeat('x', 70))->setline(1)
call matchaddpos('ErrorMsg', [[1, 51]])
]=])
screen:expect([[
^xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx{1:]} |
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
|
]])
end)
it('is shown with incsearch vim-patch:8.2.3940', function()
local screen = Screen.new(75, 6)
screen:set_default_attr_ids({
[0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText
[1] = {background = Screen.colors.Yellow}, -- Search
[2] = {background = Screen.colors.Red, foreground = Screen.colors.White}, -- ErrorMsg
})
screen:attach()
exec([[
set incsearch
call setline(1, range(20))
call matchaddpos('ErrorMsg', [3])
]])
screen:expect([[
^0 |
1 |
{2:2} |
3 |
4 |
|
]])
feed(':s/0')
screen:expect([[
{1:0} |
1 |
{2:2} |
3 |
4 |
:s/0^ |
]])
end)
it('on a Tab vim-patch:8.2.4062', function()
local screen = Screen.new(75, 10)
screen:set_default_attr_ids({
[0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText
[1] = {background = Screen.colors.Red, foreground = Screen.colors.White}, -- ErrorMsg
})
screen:attach()
exec([[
set linebreak
call setline(1, "\tix")
call matchadd('ErrorMsg', '\t')
]])
screen:expect([[
{1: ^ }ix |
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
|
]])
end)
end)