37

I love the "hlsearch" setting, but after I'm done searching, I find it obnoxious. Especially if I search for something that has a lot of matches. I know that I can turn this off with

:set nohlsearch

But this takes a whole 16 keystrokes, and even more annoyingly, I have to turn it back on for my next search with

:set hlsearch    

Is there a way I can have hlsearch automatically toggle on when I start searching, and off when I am done searching? For example, if I enter insert mode, or modify the text, have hlsearch turn off without any additional keystrokes?

6
  • 4
    Define automatically.
    – Antony
    Commented Jul 12, 2016 at 17:16
  • @Antony As in, if I'm making edits, or in insert mode, it will turn off without me needing to press any buttons. If I start searching with / or ?, or if I press n or N, it will turn on without me needing to press any more buttons.
    – DJMcMayhem
    Commented Jul 12, 2016 at 17:18
  • 2
    Oh and define "done" searching Commented Jul 12, 2016 at 17:53
  • 1
    :nno <BS> :set hls!\|set hls?<CR> -- one line, one keypress, state feedback, and doesn't try to second-guess when you may or may not want highlighting. Sometimes I want highlighting left on the screen when editing. Sometimes I don't, e.g. using / as a motion with an operator.
    – Antony
    Commented Jul 12, 2016 at 19:57
  • nnoremap <M-\> :set hlsearch!<CR><Bar>:echo 'hlsearch: ' . ['Off', 'On'][&hlsearch]<CR> Commented Jul 13, 2016 at 7:07

12 Answers 12

42

There is a much more convenient way. Rather than using

:set nohlsearch

which actually turns the hlsearch setting off, use

:nohls

This will only turn hlsearch off until you search again. From :help nohls

                 *'hlsearch'* *'hls'* *'nohlsearch'* *'nohls'*
'hlsearch' 'hls'    boolean (default off)
            global
            {not in Vi}
            {not available when compiled without the
            |+extra_search| feature}

    ...

    When you get bored looking at the highlighted matches, you can turn it
    off with |:nohlsearch|.  This does **not change the option value**, as
    soon as you use a search command, the highlighting comes back.

However, this solution isn't perfect, since you still have to type out :nohls which is pain to do after every search. You can get around this with a mapping, e.g.

nnoremap <esc><esc> :silent! nohls<cr>

But there is an even better solution! haya14busa/incsearch.vim. This is, at least in my opinion, an essential vim plugin. The main feature is that all search matches are highlighted in real time, as you are typing out your regex. For example:

enter image description here

However, a secondary feature that is also provided is the option to immediately toggle hlsearch on and off when you start/stop searching. To enable this feature, you will have to add

set hlsearch
let g:incsearch#auto_nohlsearch = 1
map n  <Plug>(incsearch-nohl-n)
map N  <Plug>(incsearch-nohl-N)
map *  <Plug>(incsearch-nohl-*)
map #  <Plug>(incsearch-nohl-#)
map g* <Plug>(incsearch-nohl-g*)
map g# <Plug>(incsearch-nohl-g#)

to your .vimrc.

If you have any other n mappings, you will have to turn these off. For example, I used to have

nnoremap n nzz
nnoremap N Nzz

These two mappings are not compatible with eachother!

5
  • Since you are doing a self answer i'd like to suggest that you also add another problem with set hlsearch. If you have it defined in vimrc it will overwrite :noh every time you source the vimrc. To sort this out I have if !&hlsearch | set hlsearch | endif in my vimrc. (And this is another problem that the plugin solves.)
    – grochmal
    Commented Jul 12, 2016 at 17:59
  • Dunno, seems like a whole heap of code and config for not a lot of gain to me. In fact it makes the target of your incremental search harder to spot, making it less useful for quick navigation.
    – Antony
    Commented Jul 12, 2016 at 19:48
  • +1 for a great plugin answering question and doing a lot more!
    – RichVel
    Commented Feb 2, 2017 at 16:04
  • :noh is an even shorter alias than :nohls
    – wisbucky
    Commented Nov 16, 2021 at 7:36
  • The features of this plugin have now been implemented into Vim. Do set incsearch
    – ei2
    Commented Jun 28, 2022 at 14:49
14

vim-cool is a simple plugin that does just this.

Vim-cool disables search highlighting when you are done searching and re-enables it when you search again.

It works without remapping by using the CursorMoved and InsertEnter autocommands.

1
  • This technique (using autocommands) is way better than my answer, and I can't believe I didn't think of it when I wrote mine. Upvote.
    – Rich
    Commented Aug 30, 2017 at 12:35
7

I have found it more intuitive to remap the Ctrl-L repaint to include :nohls:

nnoremap <C-L> :nohls<cr><C-L>
1
  • Welcome to Vi and Vim! Thank you for sharing your knowledge on what is admittedly an old question. High quality answers, as you might have noticed, generally come with some explanation of what the code is doing (this is especially helpful for newer vimmers who might land here without much knowledge). It can also be a good idea to the relevant :help sections!
    – D. Ben Knoble
    Commented Dec 19, 2019 at 22:48
6

I use <Leader><Enter> as a shortcut to :noh. (My leader is ,, so it's pretty close)

This will turn off the highlights until your next search.

6

As you've already noted in your own answer, it's far more efficient to turn off highlighting with the :nohlsearch command (which can be abbreviated to :noh) rather than turning off the entire feature and then turning it back on the next time you search.

If you want to switch off highlighting every time you use i to enter insert mode, you can create a simple mapping to do so:

:nnoremap i :noh<cr>i

It's left as an exercise for the reader to create similar mappings for other commands where they want highlighting switched off.

More recent versions of Vim have an InsertEnter autocommand which you might think could be used to easily create a cleaner implementation of switching off highlighting, but unfortunately, the :nohlsearch command has no effect within an autocommand. A possible workaround is instead to reset the search pattern when entering insert mode, but that obviously has side effects you may not desire:

augroup ClearSearch
  autocmd!
  autocmd InsertEnter * let @/ = ''
augroup END

There is, however, a better technique, which is to use feedkeys from the autocommand. This is what the vim-cool plugin mentioned in Jon Parise's answer uses.

4

It might sound stupid or naive, but what I do when I want to stop the highlighting is I search for a random string that (virtually certainly) is not present in the document. Something like this:

/skljdfhadhfs

Granted, it does take a few key strokes, but they are really random, so they can be typed in no time.

2
  • 2
    But this makes n and N no longer work, and also things like :%s//something or :g//something. It also clutters your search history
    – DJMcMayhem
    Commented Jul 3, 2019 at 18:38
  • 1
    Yes, but my (probably incorrect) assumption is that since you don't need highlighting any more, you don't care about that particular search either. Cluttering the search history is a real issue, if one relies on it.
    – Kostas
    Commented Jul 3, 2019 at 18:40
2

I'm surprised that the following solution hasn't been posted:

augroup vimrc-incsearch-highlight
  autocmd!
  autocmd CmdlineEnter /,\? :set hlsearch
  autocmd CmdlineLeave /,\? :set nohlsearch
augroup END
2
  • 1
    Welcome to Vi and Vim! (Nice nick/avatar, lol.) It might be worth an edit explaining what this does/how it works
    – D. Ben Knoble
    Commented Apr 27, 2021 at 20:12
  • 1
    probably because the question predates the CmdlineEnter autocommand from Vim. Also, this comes right from the help section :h 'incsearch' Commented Apr 28, 2021 at 5:44
0

I use <Leader><Enter> as a shortcut to :hls and have my leader set as space.

let mapleader = "\<Space>"
nmap <silent> <leader><Esc> :set hls!<cr>

After searching an item will be highlighted, to turn it off, hit <Space><Esc>. And if you decide you want to redisplay the search results, hit <Space><Esc>. The hls! means map this key binding to toggle the setting for hls (shorthand for hlsearch, i.e. search result highlighting) (so the ! toggles the setting right before it).

0

I know I'm a little bit late, but there is a plugin called is.vim. Maybe it can be useful for someone, here is the link: https://vimawesome.com/plugin/is-vim

0

Remark: turning off hlsearch (as in this answer) won't clear the search register.

It means that you can still jump to next/prev matches but with no highlights which could be annoying for some users as it was for me.

To clear the search register itself and the highlight in one command you may use:

:let @/ = ""
6
  • 1
    Welcome to Vim :-) I'm not sure I understand your answer. At first glance it looks more like a comment. Maybe could you elaborate a bit more. Commented Dec 30, 2022 at 12:53
  • Thanks, and apologies for the confusion. It's a comment to remind that clearing the highlight on search matches won't clear the search register itself. it means that you can still jump to next/prev matches but with no highlights which could be annoying for some users as it was for me. Yet, to clear the search register itself and the highlight in one command you may use ` let @/ = "" `. BR
    – Aiankan
    Commented Dec 30, 2022 at 17:43
  • 1
    Thanks for your reply. Maybe could you expand your answer to repeat the part of the answer you are refering to and to include your suggestion about the search register :-) Commented Dec 30, 2022 at 18:11
  • 1
    @VivianDeSmedt, here. Thanks for being begginer friendly. Enjoy your day.
    – Aiankan
    Commented Dec 31, 2022 at 9:09
  • You are welcome :-) Since the sequence of answer vary with votes we try to encourage contributor to have answers that do not depend of other answers. I have slightly reformulated your answer in that direction, feel free to cancel my edition if it do not go in the direction you intended. Commented Dec 31, 2022 at 11:11
0

i use buildin vim function to solve it, just add this to .vimrc:

set hls
augroup clearhlsearch
 autocmd!
 autocmd InsertEnter,VimEnter,CursorHold * :let @/=""
augroup END

description: set highlight search to enable set hls make auto command group clearhlsearch, line 1 clear previous autocommand buffer with autocmd!, line 2 set search buffer to " " when open vim VimEnter or exit from insert mode InsertLeave, or cursor not move CursorHold (it depend to set updatetime) you can get my vim config in here Wahyu's dotfile

1
  • 'hls' is a global setting, so you don't need setlocal Commented Mar 17, 2023 at 10:36
-2

Add this macro to your .vimrc

map #h :set hls!<CR>

This will allow you to toggle hilighting with #h

3
  • This is no different than James Affleck's answer.
    – jamessan
    Commented Nov 1, 2019 at 22:49
  • Mine seems more concise.
    – Darrel Lee
    Commented Nov 8, 2019 at 19:46
  • 3
    Why is conciseness relevant? The other post gives more information about what the parts of the command mean and this post provides no additional content.
    – jamessan
    Commented Nov 8, 2019 at 19:53

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