When I have hlsearch on and my cursor is somewhere in a highlighted search match, is it possible to detect the search highlight hl-Search with synIDattr() or a similar function?

As far as I can tell by running the following command, it doesn't seem to be:

:echo map(synstack(line('.'), col('.')), 'synIDattr(v:val, "name")')

But perhaps that makes sense as a search highlight isn't a language syntax item.

In fact I can't find any way to get a list of the current search highlight positions, which surprises me. Is this possible?

I found a number of similar questions to this but nothing that answered my question.

Motivation: my cursor is hard to see when it's on a highlighted match so I would like to change the cursor's highlight when it's on a match (and restore it when it's not). To do this I need to detect when the cursor's on a search match.

An alternative approach might be to see if the last pattern (@/) is found at/around the cursor's position.

Update: here's a small function to do that:

function! CursorInSearchMatch(...)
  if !&hlsearch || !v:hlsearch | return 0 | endif
  let [match,start,stop] = matchstrpos(getline('.'), @/, (a:0 ? a:1 : 0))
  if empty(match) | return 0 | endif
  let col = getcurpos()[2]
  if col <= start | return 0 | endif
  if col <= stop  | return 1 | endif
  return CursorInSearchMatch(stop)

I call it from CursorMoved.

  • 1
    try :help searchcount()?
    – D. Ben Knoble
    Jan 15 '21 at 18:35
  • 1
    I cover detection of search match instance containing the cursor here Can I use a different color for the selected match than for other matches ... it changes the match's highlighting rather than the cursor's but it might help (if I'm reading your need correctly). It's based on :h /\%# which is worth reading.
    – B Layer
    Jan 15 '21 at 21:09
  • @D.BenKnoble I didn't know about searchcount() – I can see it's fairly recent. searchcount().exact_match seems to detect when the cursor is in a match. Thanks! Jan 16 '21 at 10:05
  • @BLayer Thanks for that, I hadn't seen that answer and I had forgotten about /\%#. After I posted my question I wrote a small function (see my updated question) using matchstrpos() which detects when the cursor is anywhere in the search match, not just at the start. Jan 16 '21 at 10:07
  • @AndyStewart if youve managed to answer your question, post it as answer please!
    – D. Ben Knoble
    Jan 16 '21 at 13:55

I have not found a way to detect search highlighting. A character's search highlight seems to be invisible to vimscript.

Having said that, you can detect when the cursor is in a search match by other means.

  • searchcount().exact_match returns 1 if the cursor is in a search match. Thanks @D.BenKnoble.
  • /\%#@/ can be used to determine whether the cursor is at the start of a search match. Thanks @BLayer.
  • The function I added to my question can be used if searchcount() isn't available.

Now I can tell when the cursor is in a search match, I can use matchaddpos() to highlight the "current" match on CursorMoved. Here's my plugin vim-current-search-match.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.