Rich's answer using
:'<,'>w !copy_stuff is the right answer!
One alternative is to use the
You can pass it a string as input, which you can get from a register that captures the text in your range.
It's convenient to define a user command for this purpose, since then you can easily pass it a range.
For example, with your
function! CopyStuff(line1, line2)
let save_reg = getreg('"')
let save_type = getregtype('"')
silent execute a:line1 ',' a:line2 'y'
call system('copy_stuff', @")
call setreg('"', save_reg, save_type)
command! -range=% -bar CopyStuff call CopyStuff(<line1>, <line2>)
The first two lines and last line of the function body are saving and restoring the default register (so that it doesn't affect your put commands.)
The third line yanks the range (passed as arguments) into the default register.
system() call passes the contents of the default register as input for the external command.
The user-defined command is using
-range=%, which allows it to take a range, and defaults to the whole buffer if one isn't passed (you can omit the
=% part if you prefer to default to the current line.)
<line2> placeholders are replaced with the first and last line of the range when the command is executed.
-bar is there because it's good to have it, always, to be able to put another command on the same line after a
|. (Only exception if you want to handle
|s yourself in arguments, but that's seldom the case.)
Invoke it with:
Or from visual mode:
:help :command for more options available for user-defined commands (such as arguments).