How do I run an external filtering program on a part of a line?
When I do:
:'<,'>!myfilter
it always filters the whole line regardless of whether the whole line is selected or just a part of it.
Try this:
:s/\%V.*\%V./\=system('myfilter', submatch(0))[:-2]/
As an example, consider this text:
one zwei three
four fünf six
Visually select the block containing the german numbers zwei
and fünf
, and run this command:
:'<,'>s/\%V.*\%V./\=system('trans -brief', submatch(0))[:-2]/
It should translate the numbers into english:
one two three
four five six
Requires the shell utility translate-shell
.
To make the process a little easier, you could install this mapping:
xno <c-g>s :s/\%V.*\%V./\=system('', submatch(0))[:-2]/<c-r>=setcmdpos(28)[-1]<cr>
Press C-g s
while selecting your text. It should populate the command-line with:
:'<,'>s/\%V.*\%V./\=system('', submatch(0))[:-2]/
^
cursor right before
And the cursor should be correctly positioned to let you immediately type the name of the filter you want to use.
For more info, see:
:h /\%V
:h system()
:h submatch()
:h setcmdpos()
:!
and other ex commands work line-by-line, so it filters the whole lone. You cant change this behavior, but you can do workarounds... a good answer will demonstrate such workarounds.