Suppose you want to wrap the selected text with [[
and ]]
. Make your selection and then run this command:
:'<,'>s/\%V.*\%V./[[&]]/
Note that if you type : in visual mode then the '<,'>
is inserted for you, so you only need to type :s to get the :'<,'>s
at the beginning of the command.
What’s going on here?
\%V
is a special matching atom. For whatever reason, the docs say, “To make sure the whole pattern is inside the Visual area put it at the start and just before the end of the pattern” (emphasis added). That’s why there’s an extra .
in the pattern. Here’s what each atom in the pattern means:
\%V
: match the beginning of the visual selection.
.*
: match everything from the beginning of the selection up to, but not including, the final character.
\%V
: match “just before the end” of the selection.
.
: match the final character in the selection.
Despite these complexities, we can use the convenient &
in the replacement string to mean “the entire string that was selected.”
Caveat
This will not work as expected if your selection spans multiple lines: each line will end up with its own [[
and ]]
(or whatever strings you’re using). I tried to replace the .
with \_.
in the pattern but that just made things weird—text was inserted well outside of the visual selection.
Improvements to my answer would be greatly appreciated!