diff options
-rw-r--r-- | src/nvim/match.c | 35 | ||||
-rw-r--r-- | src/nvim/testdir/test_search.vim | 11 | ||||
-rw-r--r-- | test/functional/ui/searchhl_spec.lua | 27 |
3 files changed, 58 insertions, 15 deletions
diff --git a/src/nvim/match.c b/src/nvim/match.c index f6d2fe13c4..c946ed5e02 100644 --- a/src/nvim/match.c +++ b/src/nvim/match.c @@ -560,6 +560,22 @@ void prepare_search_hl(win_T *wp, match_T *search_hl, linenr_T lnum) } } +/// Update "shl->has_cursor" based on the match in "shl" and the cursor +/// position. +static void check_cur_search_hl(win_T *wp, match_T *shl) +{ + long linecount = shl->rm.endpos[0].lnum - shl->rm.startpos[0].lnum; + + 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 + linecount || wp->w_cursor.col < shl->rm.endpos[0].col)) { + shl->has_cursor = true; + } else { + shl->has_cursor = false; + } +} + /// Prepare for 'hlsearch' and match highlighting in one window line. /// Return true if there is such highlighting and set "search_attr" to the /// current highlight attribute. @@ -609,20 +625,14 @@ bool prepare_search_hl_line(win_T *wp, linenr_T lnum, colnr_T mincol, char_u **l } else { shl->endcol = MAXCOL; } - if (shl->rm.endpos[0].lnum != shl->rm.startpos[0].lnum) { - shl->lines = shl->rm.endpos[0].lnum - shl->rm.startpos[0].lnum; - } else { + shl->lines = shl->rm.endpos[0].lnum - shl->rm.startpos[0].lnum; + if (shl->lines == 0) { 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; + if (shl == search_hl) { + check_cur_search_hl(wp, shl); } // Highlight one character for an empty match. @@ -723,6 +733,11 @@ int update_search_hl(win_T *wp, linenr_T lnum, colnr_T col, char_u **line, match shl->endcol = MAXCOL; } + // check if the cursor is in the match + if (shl == search_hl) { + check_cur_search_hl(wp, shl); + } + if (shl->startcol == shl->endcol) { // highlight empty match, try again after it shl->endcol += utfc_ptr2len(*line + shl->endcol); diff --git a/src/nvim/testdir/test_search.vim b/src/nvim/testdir/test_search.vim index 24ecc58281..d359e69f91 100644 --- a/src/nvim/testdir/test_search.vim +++ b/src/nvim/testdir/test_search.vim @@ -951,7 +951,7 @@ func Test_hlsearch_cursearch() let lines =<< trim END set hlsearch scrolloff=0 - call setline(1, ['one', 'foo', 'bar', 'baz', 'foo', 'bar']) + call setline(1, ['one', 'foo', 'bar', 'baz', 'foo the foo and foo', 'bar']) hi Search ctermbg=yellow hi CurSearch ctermbg=blue END @@ -964,7 +964,14 @@ func Test_hlsearch_cursearch() call term_sendkeys(buf, "n") call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_single_line_2', {}) - call term_sendkeys(buf, "?\<CR>") + call term_sendkeys(buf, "n") + call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_single_line_2a', {}) + + call term_sendkeys(buf, "n") + call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_single_line_2b', {}) + + call term_sendkeys(buf, ":call setline(5, 'foo')\<CR>") + call term_sendkeys(buf, "0?\<CR>") call VerifyScreenDump(buf, 'Test_hlsearch_cursearch_single_line_3', {}) call term_sendkeys(buf, "gg/foo\\nbar\<CR>") diff --git a/test/functional/ui/searchhl_spec.lua b/test/functional/ui/searchhl_spec.lua index 84dc3c59bb..56ff8a4101 100644 --- a/test/functional/ui/searchhl_spec.lua +++ b/test/functional/ui/searchhl_spec.lua @@ -163,15 +163,25 @@ describe('search highlighting', function() end) it('works for multiline match', function() - command([[call setline(1, ['one', 'foo', 'bar', 'baz', 'foo', 'bar'])]]) + command([[call setline(1, ['one', 'foo', 'bar', 'baz', 'foo the foo and foo', 'bar'])]]) feed('gg/foo<CR>') screen:expect([[ one | {2:^foo} | bar | baz | + {1:foo} the {1:foo} and {1:foo} | + bar | + /foo | + ]]) + feed('n') + screen:expect([[ + one | {1:foo} | bar | + baz | + {2:^foo} the {1:foo} and {1:foo} | + bar | /foo | ]]) feed('n') @@ -180,11 +190,22 @@ describe('search highlighting', function() {1:foo} | bar | baz | - {2:^foo} | + {1:foo} the {2:^foo} and {1:foo} | + bar | + /foo | + ]]) + feed('n') + screen:expect([[ + one | + {1:foo} | + bar | + baz | + {1:foo} the {1:foo} and {2:^foo} | bar | /foo | ]]) - feed('?<CR>') + command([[call setline(5, 'foo')]]) + feed('0?<CR>') screen:expect([[ one | {2:^foo} | |