Rich's answer using :'<,'>w !copy_stuff
is the right answer!
One alternative is to use the system()
function.
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 copy_stuff
:
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)
endfunction
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.
Finally, the 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.)
The <line1>
and <line2>
placeholders are replaced with the first and last line of the range when the command is executed.
The -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:
:CopyStuff
Or from visual mode:
:'<,'>CopyStuff
See :help :command
for more options available for user-defined commands (such as arguments).