I am trying to write a function which I bind to "n" and "N" to highlight the current search pattern. That part works.
I would like to detect when the cursor wraps to the first match in the buffer (when 'search hit BOTTOM' is shown), and use a different highlight then.
But I fail getting the line where the search pattern first appears.
I know hot to get a list of lines with a global and p
flag but am not sure if and how I should trim it.
g/pattern/p
I can also use search()
with n
flag (not to move the cursor), but I am only able to get the previous match with it.
So I tried to hack my way around the problem by setting the cursor position to the top of the file, then using search()
to get the first line including the pattern, then restoring the cursor position. It seems to get the next search despite moving the cursor.
That's what it looks like:
function! HLCurrent() abort
if exists("currmatch")
call matchdelete(currmatch)
endif
let patt = '\c\%#'.@/ "set pattern
let currline = line('.') "save current line
let currcol = col('.') "save current column
call cursor(1, 1) "move to top of file
let firstmatchline = search(patt) "get first line with pattern
call cursor(currline, currcol) "restore cursor
if firstmatchline == getline('.') "always true
let currmatch = matchadd('Todo', match, 101)
else "never in else
let currmatch = matchadd('IncSearch', match, 101)
endif
redraw
endfunction
nnoremap <silent> n n:call HLCurrent()<cr>
nnoremap <silent> N N:call HLCurrent()<cr>
TL;DR
So the question is, how can I get the line of the first occurrence of a pattern properly?
line()
before and after? If the cursor moves up then you’ve wrapped around.W
flag ofsearch
, it allows you to forbid the wrap around