2

I am trying to use a vim function to search whether :noh has been set or not

This is similar to question found here except that question does not take :noh into account

One way to search from a function is to use let @/ = 'needle'

However, after I use :noh, this no longer works for any of my functions. I have to call :set hlsearch outside of my function for the search to work. Example

function! Needle()
  let @/ = 'needle'
endfunction
nnoremap try1 :call Needle()<return>
nnoremap try2 :call Needle()<return>:set hlsearch<return>

the mapping "try1" does not work. The mapping "try2" does work.

Question - is there any way to get :set hlsearch to work from the function?

update - I found that search is indeed being performed, but the highlight is removed. This can be undone by pressing n in normal mode. It's still not executed from the funciton, but is closer to the solution I am looking for.

function! Needle()
  let @/ = 'needle'
endfunction
nnoremap try1 :call Needle()<return>
nnoremap try2 :call Needle()<return>n

"try1" will not work but "try2" will

9
  • Per :h :noh, highlighting state is saved and restored when executing user functions. Based on that: not possible.
    – B Layer
    Aug 27 at 21:13
  • @BLayer adding set hlsearch and return ":let v:hlsearch = v:true\<CR>" worked. Although to be honest, I need to do some research on the return ":let v:hlsearch = v:true\<CR>" part because I don't understand what that is doing and I don't like having code I don't understand Aug 27 at 21:19
  • Well, that's not actually doing anything in a user function which would contradict my first comment. :) But, funny thing is I was just about to point you to something that suggests this exact same thing. See last comment under vi.stackexchange.com/a/3149/11054
    – B Layer
    Aug 27 at 21:20
  • As for what it is doing, your mapping that calls that function has to have <expr>. That says the the right hand side of the mapping will be evaluated as a Vim expression (normally it's interpreted as is ... used literally) and the result will be the actual mapped action. So that makes sense here...the return value of the function (a string) is run as a command and the effect is to do set hlsearch outside the function.
    – B Layer
    Aug 27 at 21:23
  • 1
    Oh, I'll have to give that a try! Thanks @BLayer!! Aug 27 at 22:40
2

It is a little tricky but this can be done. First you have to search using let @/ = 'needle'. This initiates the search. However, none of the highlights appear. To get the highlights, you simply need to go to the "next" instance with :normal! n, which will highlight all instances and move the cursor to the next instance. Final solution:

function! Needle()
  let @/ = 'needle'
  :normal! n
endfunction

nnoremap ,needle :call Needle()<return> 

Thanks B Layer and Ben Knoble for the help!

2
  • 1
    Does :normal! n work in the function?
    – D. Ben Knoble
    Aug 28 at 11:52
  • That did the trick! Thanks @D.BenKnoble Sep 7 at 21:37
0

to check the state of :noh its hlsearch or nohlsearch, you can check it one of these ways:

:set hlsearch?

or

:set nohlsearch?
1
  • Once again, this has nothing to do with the question being asked, which is not about checking the value of the option. We appreciate your enthusiasm for answering and contributing, and we ask that you read the question carefully and focus your answer to it.
    – D. Ben Knoble
    Aug 28 at 11:51

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.