vim-patch:8.2.4759: CurSearch highlight does not work for multi-line match

Problem:    CurSearch highlight does not work for multi-line match.
Solution:   Check cursor position before adjusting columns. (closes vim/vim#10133)
693ccd1160
This commit is contained in:
zeertzjq 2022-04-21 19:59:25 +08:00
parent e6dec30332
commit 4b19f94c28
4 changed files with 88 additions and 54 deletions

View File

@ -1027,6 +1027,7 @@ typedef struct {
colnr_T startcol; // in win_line() points to char where HL starts
colnr_T endcol; // in win_line() points to char where HL ends
bool is_addpos; // position specified directly by matchaddpos()
bool has_cursor; // true if the cursor is inside the match, used for CurSearch
proftime_T tm; // for a time limit
} match_T;

View File

@ -373,6 +373,7 @@ static int next_search_hl_pos(match_T *shl, linenr_T lnum, posmatch_T *posmatch,
shl->rm.endpos[0].lnum = 0;
shl->rm.endpos[0].col = end;
shl->is_addpos = true;
shl->has_cursor = false;
posmatch->cur = found + 1;
return 1;
}
@ -585,6 +586,7 @@ bool prepare_search_hl_line(win_T *wp, linenr_T lnum, colnr_T mincol, char_u **l
shl->lines = 0;
shl->attr_cur = 0;
shl->is_addpos = false;
shl->has_cursor = false;
if (cur != NULL) {
cur->pos.cur = 0;
}
@ -612,6 +614,17 @@ bool prepare_search_hl_line(win_T *wp, linenr_T lnum, colnr_T mincol, char_u **l
} else {
shl->lines = 1;
}
// check if the cursor is in the match before changing the columns
if (wp->w_cursor.lnum >= shl->lnum
&& wp->w_cursor.lnum <= shl->lnum + shl->rm.endpos[0].lnum
&& (wp->w_cursor.lnum > shl->lnum
|| wp->w_cursor.col >= shl->rm.startpos[0].col)
&& (wp->w_cursor.lnum < shl->lnum + shl->lines
|| wp->w_cursor.col < shl->rm.endpos[0].col)) {
shl->has_cursor = true;
}
// Highlight one character for an empty match.
if (shl->startcol == shl->endcol) {
if ((*line)[shl->endcol] != NUL) {
@ -676,12 +689,7 @@ int update_search_hl(win_T *wp, linenr_T lnum, colnr_T col, char_u **line, match
}
// Highlight the match were the cursor is using the CurSearch
// group.
if (shl == search_hl
&& (HL_ATTR(HLF_LC) || wp->w_hl_ids[HLF_LC])
&& wp->w_cursor.lnum == lnum
&& wp->w_cursor.lnum < shl->lnum + shl->lines
&& wp->w_cursor.col >= shl->startcol
&& wp->w_cursor.col < shl->endcol) {
if (shl == search_hl && shl->has_cursor && (HL_ATTR(HLF_LC) || wp->w_hl_ids[HLF_LC])) {
shl->attr_cur = win_hl_attr(wp, HLF_LC) ? win_hl_attr(wp, HLF_LC) : HL_ATTR(HLF_LC);
} else {
shl->attr_cur = shl->attr;

View File

@ -968,7 +968,17 @@ func Test_hlsearch_cursearch()
call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_single_line_3', {})
call term_sendkeys(buf, "gg/foo\\nbar\<CR>")
call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_multiple_line', {})
call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_multiple_line_1', {})
call term_sendkeys(buf, ":call setline(1, ['---', 'abcdefg', 'hijkl', '---', 'abcdefg', 'hijkl'])\<CR>")
call term_sendkeys(buf, "gg/efg\\nhij\<CR>")
call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_multiple_line_2', {})
call term_sendkeys(buf, "h\<C-L>")
call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_multiple_line_3', {})
call term_sendkeys(buf, "j\<C-L>")
call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_multiple_line_4', {})
call term_sendkeys(buf, "h\<C-L>")
call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_multiple_line_5', {})
call StopVimInTerminal(buf)
call delete('Xhlsearch_cursearch')

View File

@ -163,53 +163,68 @@ describe('search highlighting', function()
end)
it('works for multiline match', function()
insert([[
one
foo
bar
baz
foo
bar]])
feed('gg/foo<CR>')
screen:expect([[
one |
{2:^foo} |
bar |
baz |
{1:foo} |
bar |
/foo |
]])
feed('n')
screen:expect([[
one |
{1:foo} |
bar |
baz |
{2:^foo} |
bar |
/foo |
]])
feed('?<CR>')
screen:expect([[
one |
{2:^foo} |
bar |
baz |
{1:foo} |
bar |
?foo |
]])
feed('gg/foo\\nbar<CR>')
screen:expect([[
one |
{2:^foo} |
{1:bar} |
baz |
{1:foo} |
{1:bar} |
/foo\nbar |
]])
command([[call setline(1, ['one', 'foo', 'bar', 'baz', 'foo', 'bar'])]])
feed('gg/foo<CR>')
screen:expect([[
one |
{2:^foo} |
bar |
baz |
{1:foo} |
bar |
/foo |
]])
feed('n')
screen:expect([[
one |
{1:foo} |
bar |
baz |
{2:^foo} |
bar |
/foo |
]])
feed('?<CR>')
screen:expect([[
one |
{2:^foo} |
bar |
baz |
{1:foo} |
bar |
?foo |
]])
feed('gg/foo\\nbar<CR>')
screen:expect([[
one |
{2:^foo} |
{2:bar} |
baz |
{1:foo} |
{1:bar} |
/foo\nbar |
]])
command([[call setline(1, ['---', 'abcdefg', 'hijkl', '---', 'abcdefg', 'hijkl'])]])
feed('gg/efg\\nhij<CR>')
screen:expect([[
--- |
abcd{2:^efg} |
{2:hij}kl |
--- |
abcd{1:efg} |
{1:hij}kl |
/efg\nhij |
]])
feed('n')
screen:expect([[
--- |
abcd{1:efg} |
{1:hij}kl |
--- |
abcd{2:^efg} |
{2:hij}kl |
/efg\nhij |
]])
end)
end)