5
This is a sample sentence.
This is a second sample sentence.

Let's say I select 'is a' of the first sentence. Now I want to change all occurrences of what is selected (including the selection itself) to 'is not a'. How do I do that?

  • 1
    @le0m You want a mapping in visual mode which replaces the visual selection with an arbitrary string ? If so you could try this: xnoremap ,s y:<C-U>let replacement = input('Enter replacement string: ') <bar> %s/<C-R>"/\=replacement/g<CR> (Here the mapping is ,s but you could change it to what you want). – saginaw Feb 26 '16 at 15:13
4

You could execute the following command: :%s/is a/is not a :

  • Select and yank is a with your favorite method (visual selection and y, y2w with cursor on is, etc...)
  • Enter command mode with :
  • Begin to write your replacement command %s/
  • Insert the text to replace with Ctrl+r and ". (see Note2)
  • Finish to write the replacement command /is not a
  • Execute the replacement command with Enter

Note if you have several occurrences of is a on same line use the g tag to substitute all occurrences of a same line: :%s/is a/is not a/g

Note 2 When you are in insert mode Ctrl+r allows you to choose a register and to insert its content. When you yanked your text in the first step you yanked it to the unnamed register which is accessible with ". So when you type Ctrl+r followed by " you're inserting the text you yanked before.

See :h i_CTRL-R and :h registers as advised by @VanLaser for more details about registers.

See :h :s for more informations about the search and replace function.

Edit I had not seen the comment of @VanLaser who basically gave the same solution, sorry.

4

Using gn and . for quick replacements

You can use gn motion to make replacing matches quicker. Simply search for your text

/foo

Then change the current match with the change operator, c, and the gn motion.

cgnbar<esc>

Simply repeat this via the . command as many times as you wish. You can also use n to jump to the next match in case you want to skip any matches.

There is a nice Vimcasts episode on this topic: Operating on search matches using gn

For more help see:

:h gn
:h /
:h .
:h n

Aside: Tips on searching for selected text

Vim's help doc provides the following mapping under :h visual-search:

:vmap X y/<C-R>"<CR>

This is better than searching by hand however it does not take escaping into consideration and causes the side effect of overwriting the unnamed register. Some of this can be mitigated by using \V to turn on "very 'nomagic'".

Personally I would get a visual star plugin (there are few out there). There is a nice Vimcast about this: Search for the selected text. This means you can select the line visually and then press *.

If a plugin isn't your thing you can add the following mapping to your vimrc to mimic a visual star plugin:

xnoremap * :<c-u>let @/=@"<cr>gvy:let [@/,@"]=[@",@/]<cr>/\V<c-r>=substitute(escape(@/,'/\'),'\n','\\n','g')<cr><cr>

Note: The mapping above will not work for visual-block mode.

For more help see:

:h visual-search
:h c_CTRL-R
:h /\V
:h /magic
  • Great answer, +1 ! With a mutiline pattern, I think the last mapping wouldn't work as expected. For example, if you have a buffer containing several groups of 2 consecutive lines foo and bar, you select one of them and copy it with y, and type /<C-R>", instead of searching for foo\nbar\n, you will search for foo^Mbar^M, because Vim will automatically interpret \n as a literal carriage return whose caret notation is ^M. At least, it seems to happen on my machine, maybe I have some wrong settings though. – saginaw Feb 26 '16 at 18:47

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.