How do I keep vim from highlighting matches after a replace?

13

8

I have set hlsearch in my ~/.vimrc. This is normally very useful, but it's annoying to have to do :noh after I do a replace like '<,'>s/$/',/ (which highlights the end of every line after I run it). How do I get vim to not highlight after replacing like this?

I'm on Ubuntu 9.04 with vim 7.2. I have the same problem on OS X 10.6 (also vim 7.2). Something that would work on both would be desireable.

UPDATE: All the answers I've received are just adding a key mapping to do :noh (or an equivalent). I really try to avoid custom key behaviors that I would really get used to, but then make me fail miserably without them (e.g. at a friend's computer, etc.). I would like vim to automatically do :noh after doing a replacement. That is, I only want hlsearch when using / or * (maybe a few other cases), but not other times.

Benjamin Oakes

Posted 2009-10-27T15:52:38.203

Reputation: 2 585

Answers

7

If you don't want to permanently disable, you can bind a key to toggle the highlight as suggested in this answer to a similar question on stackoverflow.

map  <F12> :set hls!<CR>
imap <F12> <ESC>:set hls!<CR>a
vmap <F12> <ESC>:set hls!<CR>gv

If you want to permanently disable the highlight:

11.1. After I searched for a text with a pattern, all the matched text
      stays highlighted. How do I turn off the highlighting
      temporarily/permanently?

The 'hlsearch' option controls whether all the matches for the last
searched pattern are highlighted or not. By default, this option is not
enabled. If this option is set in a system-wide vimrc file, then you can
turn off the search highlighting by using the following command:

    :set nohlsearch

(from the VIM FAQ)

Doug Harris

Posted 2009-10-27T15:52:38.203

Reputation: 23 578

A little while ago, I started turning off highlighting by default and turning it on when I want it, like you suggested. Still not perfect, but it's better. – Benjamin Oakes – 2010-04-21T16:24:23.310

2I was aware of this option. The issue is that I'm usually not searching for what I want to replace, so it's pointless to highlight in most cases that I replace. However, it's very useful for when I am searching for something, so I don't want it to go completely away. – Benjamin Oakes – 2009-10-29T18:31:12.617

@Benjamin: You did implicitly search for it. That's what :s does. Searches for a pattern and then performs a transformation on the match(es). Using :nohl is the right solution as it turns off the highlight of the current search pattern until the next search is performed. It does this without changing the state of the 'hlsearch' option or affecting the stored value of the previous search term. – jamessan – 2009-12-02T17:47:12.620

2@jamessan: I understand that it's a search and replace. It's just that I don't need it highlighted then. Mostly an annoyance more than anything. – Benjamin Oakes – 2009-12-04T15:31:15.517

9

I have two different solutions, both pretty good, each with a nuanced different behavior. My favorite is option 2:

  1. I have the following 2 lines in my .vimrc:

    autocmd cursorhold * set nohlsearch
    autocmd cursormoved * set hlsearch
    

    The first one waits for a timeout (not configurable) if the cursor doesn't move and turns off hlsearch. The second one turns it back on if the cursor moves again.

    It's not a perfect solution, but it works for me (and will be close to perfect when the timeout is configurable -- for now, the timeout is tied to a builtin timer for vim.)

  2. Or you can try these lines:

    autocmd cursorhold * set nohlsearch
    noremap n :set hlsearch<cr>n
    noremap N :set hlsearch<cr>N
    noremap / :set hlsearch<cr>/
    noremap ? :set hlsearch<cr>?
    

This turns off hlsearch after a brief timeout of no cursor movement and turns it back on for the standard search commands. It doesn't cover all of the possibilities of turning hlsearch back on, but it's enough of a starter for proof of concept.

user19953

Posted 2009-10-27T15:52:38.203

Reputation:

The caveat of 2. is that it makes searching with visual mode V not work – Bryce Guinta – 2016-06-10T17:47:53.667

I've modified the first line in option 1 with the following

  `autocmd cursorhold * set nohlsearch | let @/ = ""`


This will clear the search register as well as remove the highlight. Haven't spent much time with this set up but I wanted to put it out there for those who end up here. – Berkeley Martinez – 2019-01-16T23:56:25.340

Thanks for the update -- didn't see it until just now. (Looks like you just added it too? Funny that.) This is a cool concept; I'll have to play around with it. – Benjamin Oakes – 2009-12-03T14:58:03.930

2

I just type "/asdf" (assuming "asdf" is not in the file) to get rid of the highlighting. I know it's pretty simplistic, but it works for me.

Greg Graham

Posted 2009-10-27T15:52:38.203

Reputation: 296

2That's the same idea as :noh, but it doesn't always work. :) Funny you mention that, though: I used to have a friend who always typed his name because it would come up less often than something like "asdf" in what he wrote. (Kinda funny, I think.) – Benjamin Oakes – 2009-12-03T14:57:13.713

True. Maybe I'll remember :noh next time. – Greg Graham – 2009-12-03T20:28:04.640

1

Put the following in your .vimrc file:

nnoremap <silent> <F11> :exe ":silent! normal /$^\r"<CR>

This will silently hide the highlighted search term but does not disable the :set hlsearch feature. It is activated again on the next search.

Gregor Müllegger

Posted 2009-10-27T15:52:38.203

Reputation: 143

It's better to simply use the builtin command designed for this purpose -- :nohl. Then you don't blow away the contents of your search register, which is used for things like jumping to the next match, default value of a pattern when none is specified, etc. – jamessan – 2009-12-02T17:45:19.410

Yeah, but it has annoyed me that my next search wasn't highlighted as supposed. So I come up with this quick solution. It might be also dirty but it works. I think for this is acceptable for vim - even if I wouldn't use "dirty" things in a source code of a real, big project. – Gregor Müllegger – 2010-01-18T23:23:02.363

1

Another possibility is resetting the @/ register (which is actually a read-write register) after doing the substitution. This restores the previous highlight:

command! -nargs=* -range S
\ let atslash=@/|exe ':'.<line1>.','.<line2>.'s'.<q-args>|let @/=atslash

However, this still has a few problems:
- instead of modifying :s, it defines a new command. While it is possible to use cabbrev to map :s to :S, I know no way to catch all constructions such as :<range>s.
- if you used :nohl previously to hide just one search, then this will re-highlight the previous search. I know no way to find if :nohl was called previously. (It might be possible to go around this and also override the :nohl command, but this would also require overriding all search commands, which might be too much...).

Circonflexe

Posted 2009-10-27T15:52:38.203

Reputation: 159