vimtricks.wiki Concise Vim tricks, one at a time.

How do I substitute text only within my last visual selection, even mid-line?

Answer

:'<,'>s/\%Vold/new/g

Explanation

The \%V atom in a substitute pattern restricts matches to the exact bounds of the last visual selection, including within a single line. This goes beyond the '<,'> range, which applies the command to entire lines — \%V ensures only the visually highlighted characters are affected.

How it works

  • '<,'> — the range covering the last visual selection (set automatically when you press : in visual mode)
  • \%V — a special regex atom that matches only inside the previously selected region
  • Together, :'<,'>s/\%Vold/new/g replaces old with new only where it falls within the selection

Without \%V, using just '<,'>s/old/new/g would replace old anywhere on the selected lines — even outside what you highlighted.

Example

Given this line (brackets show the visual selection):

error: [connection timed] out at line 42

With connection timed visually selected, running :'<,'>s/\%V / _/g produces:

error: [connection_timed] out at line 42

The space in out after the selection is not affected.

Tips

  • Works with both character-wise (v) and line-wise (V) selections
  • Re-enter visual mode with gv to re-select, then press : to rebuild the range
  • You can combine \%V with other atoms: \%V\s\+ matches runs of whitespace only inside the selection
  • In Neovim, \%V also works inside search() and :global patterns

Next

How do I use capture groups in Vim substitutions to rearrange or swap matched text?