Vim search and replace selected text

Viewed 78599

Let's say we have a text, and I enter visual mode and select some text. How do I quickly do a search for the highlighted text and replace it with something else?

15 Answers

Try execute the following or put in into your .vimrc

vnoremap <C-r> "hy:%s/<C-r>h//gc<left><left><left>

By pressing ctrl+r in visual mode, you will be prompted to enter text to replace with. Press enter and then confirm each change you agree with y or decline with n.

This command will override your register h so you can choose other one (by changing h in the command above to another lower case letter) that you don't use.

I have this in my vimrc:

function! GetVisual() range
    let reg_save = getreg('"')
    let regtype_save = getregtype('"')
    let cb_save = &clipboard
    set clipboard&
    normal! ""gvy
    let selection = getreg('"')
    call setreg('"', reg_save, regtype_save)
    let &clipboard = cb_save
    return selection
endfunction

vmap <leader>z :%s/<c-r>=GetVisual()<cr>/

This will grab the visual selection and start a substitution command with it.

EDIT: I should point out that this does not work with multiline visual selections. While GetVisual() doesn't have a problem returning it, I'm not sure how to properly put it into the command line. If anyone has any tips on how I might do this, please comment.

Other answers are good but they do not escape special characters. The answer of @brian kennedy shows a method to escape but it requires much code. In case of an URL for instance, escaping is mandatory or the search will stop on “:”.

As written in vim.fandom.com/wiki/Search_for_visually_selected_text, you can do a oneliner to search and escape some characters. You can escape the characters you want, I chose to escape /\: :

vnoremap // y/\V<C-R>=escape(@",'/\:')<CR><CR>

With this map, I must press // in visual mode to search the currently selected text on the whole buffer.

I was hoping there was a built in way in Vim to replace a word, without having to retype the word out in the first place. There is, although it will only work for text up to a word boundary character.

Once you've moused over the word, press * or # to highlight the word and jump to the next/previous location of it (if you don't want to change locations in the file, then press the opposite key to go back to the location you were just at).

Then just type:

%s//<your-replacement-string>

As mentioned in another person's answer, if %s receives a blank entry between the slashes, then it uses the previously searched for word. By pressing * or #, you're searching for the word under the cursor which makes it the most recently searched word.

In the end it's only six or seven keystrokes + length of replacement word to perform this and it requires no macro or editing of your .vimrc.

I don't think you can do this out of the box. But lots of people like this feature, so there's tons of macros and such (I've added it myself). Here is one you can add, for example; just press * to search for the next match on the visually selected text.

Here is a variation on Mykola's answer. I like making substitutions starting from the current line to the end of the text, then from the beginning to the current line (essentially the loop starts from the current line instead of the beginning).

vnoremap <C-r> "hy:.,$s/<C-r>h//gc \|1,.&& <left><left><left><left><left><left><left><left><left><left><left>

First, the substitution is made from the current line to the end of the text .,$, then it is repeated from the beginning to the current line \|1,.&&. The 11 <left> put the cursor in the right place.

Related