8

I think there is a distinct possibility this question has already been asked, but I can't find it.

If I am doing something like :s/foo/bar/g and then I want to call that again on the next line but with baz instead of bar, is there a faster way to do that? I feel like &baz should work, but it does not.

200_success
  • 9,549
  • 5
  • 51
  • 64
Eli Sadoff
  • 183
  • 4

2 Answers2

11

Not exactly what you ask for, but you can do that:

:s/foo/bar/g

And then:

:s//baz/g

You can use that because when you use :s the searched pattern is saved in the search register. Which you can see with :reg /.


Work in progress: You can speed up your workflow with:

nnoremap && :s<UP><C-F>F/cT/

And use it like so:

:s/foo/bar/g

and then

&&baz<CR>

Decomposing:

nnoremap &&         " define a new mapping
:s<UP>              " get the last :s command in the history
<C-F>               " use this command in the cmdline window
F/                  " go back to the last /
cT/                 " change back up to the last /

Some notes:

  • This won't work if you don't have any flag
  • This won't work if you don't have a substitute string
  • It should work otherwise

(let me know if I can improve it).

Some reading:

  • :h cmdline-window
  • :h c_CTRL-F
nobe4
  • 16,033
  • 4
  • 48
  • 81
  • 2
    That's definitely better than what I was doing before. I'll take it that unfortunately there might not be a faster way :(. – Eli Sadoff Jan 04 '17 at 22:18
  • Not AFAIK, and I'm trying to create a mapping which does what you want, but out of the box I'm pretty sure you're limited to typing again the substitute expression – nobe4 Jan 04 '17 at 22:21
5

In addition to @nobe4's answer, Damian Conway has two pretty interesting mappings to speed up search and replace actions. They come from this how i vim interview which is totally worth reading completely.

To quote him:

[...] I found I was forever doing global search-and-replaces (i.e. :%s/X/Y/g<CR>), so I eliminated the repetitious typing by stealing the never-used (by me) S command:

nmap  S  :%s//g<LEFT><LEFT>

Now I just need to type: SX/Y

But then I started noticing how often I did a /-search for some pattern and, having looked through the matches, then wanted to globally substitute all of them. Even with the S mapping that was more annoying repetition: first do the search: /pattern then do the replace: Spattern/replacement So I stole the (also never used by me) M command for that:

nmap <expr>  M  ':%s/' . @/ . '//g<LEFT><LEFT>'

Now it’s just: do the search: /pattern then replace all the matches: Mreplacement


To answer your question, I guess you could slightly modify the first mapping for something like this:

nmap  S  :s///g<LEFT><LEFT>

This way you can first make your substitution :s/foo/bar/g, go to the next line, hit S and you'll get: :s//|/g where | is the cursor, you can now type your new subsitution.

statox
  • 49,782
  • 19
  • 148
  • 225