31

Sometimes I use :s with a complicated regexp which may or may not be correct, or I'm not sure if I want to replace all matches.

Is there any way I can tell Vim to confirm every match it finds before it actually replaces the text?

5 Answers 5

37

Yes! Use the c flag for :substitute. From :help substitute:

[c]     Confirm each substitution.  Vim highlights the matching string (with
        hl-IncSearch).  You can type:                           :s_c
            'y'     to substitute this match
            'l'     to substitute this match and then quit ("last")
            'n'     to skip this match
            <Esc>   to quit substituting
            'a'     to substitute this and all remaining matches {not in Vi}
            'q'     to quit substituting {not in Vi}
            CTRL-E  to scroll the screen up {not in Vi, not available when
                        compiled without the +insert_expand feature}
            CTRL-Y  to scroll the screen down {not in Vi, not available when
                        compiled without the +insert_expand feature}

Example usage is simple as pie:

%s/old/new/gc

This is very useful, but didn't know about this until 2 weeks ago :-) And it's even available in ol' vi :-)

Bonus tip: You may also want to use :set nowrapscan; this prevents Vim from wrapping to top when it hits the bottom. I've found this to be especially useful when using the c flag.

2
  • 1
    I would also add that if you want to replace all instances of old in the same line (not just the first occurrence) you should add g at the end of the command so in total you will have %s/old/new/gc
    – e271p314
    Commented Apr 19, 2020 at 16:53
  • 1
    Oh, yeah; I have set gdefault so I tend to forgot to add it in examples @e271p314 😅 Commented Apr 19, 2020 at 18:05
24

In addition to what Carpetsmoker said:

The &incsearch (set incsearch) setting in Vim is really useful. You can use it together with a useful and little known trick.

The trick is to try out your complex regex by just using the / or ? command. Vim will use the &incsearch setting to show matches interactively. Once you're happy with the regex, you can use :%s//replacement to have vim use the previous search.

Notice how the part in // is blank (that's where you put the text to search). If you leave it blank, you are telling Vim to use the previous search regex. With this, you can type out a complex regex with / and have all the benefits of set incsearch, and then use the %s//replacement command to actually execute the search and replace.

If you want something similar to incsearch for :s commands, check out vim-over, but I just prefer using the native Vim way.

1
  • I used to use a variant of this: Just use :%s/pattern/replace/ and then press u for undo, you can see the parts that Vim changed if you have hlsearch enabled. And you can replace this text again with ^R. Commented Feb 5, 2015 at 15:35
14

My favorite interactive substitution is to search using / and go through the matches using n.

Then select match using gn and then s to substitute the text with whatever I like.

And repeat by moving to next match and pressing .

1
  • This is a very nice trick, because it is: (1) interactive, (2) you can go previous match if you accidentally skipped it (something that you cannot do using :s/old/new/gc).
    – Ayrat
    Commented Sep 12, 2018 at 8:54
5

In Neovim there also is the 'inccommand' option which lets you preview the result of the :s command while you type it.

3

For the benefit of everyone, incsearch was updated in vim8 to also show preview as you type the pattern

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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