How do I send a visual selection to an external command as input without replacing the selected text?
Answer
:'<,'>w !{cmd}
Explanation
The :'<,'>w !{cmd} command writes the visually selected lines to the stdin of an external shell command — without modifying the buffer. This is distinct from :'<,'>!{cmd}, which pipes the selection through the command and replaces it with the output.
This is useful when you want to pass selected text to a tool for side-effects only: copying to the clipboard, counting words, linting, running tests, or sending code to a REPL.
How it works
'<,'>is the range of the last visual selection (automatically inserted when you press:in visual mode)wis the write command, which writes the range to a destination!{cmd}specifies an external shell command as the destination — the lines are piped to its stdin- The buffer is not modified
Example
Visually select a block of Python code with V then j a few times, then:
:'<,'>w !python3
This executes the selected lines as Python code and shows the output — the buffer is unchanged.
Other practical uses:
:'<,'>w !wc -w " count words in selection
:'<,'>w !pbcopy " copy selection to macOS clipboard
:'<,'>w !xclip -sel clip " copy selection to Linux clipboard
:'<,'>w !xargs open " open URLs in selection in browser
Tips
- Compare with
:'<,'>!{cmd}which replaces the selected text with the command output - Use
:w !{cmd}(without a range) to send the entire buffer to a command - The command's output appears in the Vim message area; use
:redirto capture it