What I am trying to achieve is sending visual selections to external programs without affecting the contents of the buffer.
Let the following code block represent the current buffer. Let [<] represent the start of visual selection, and [>] represent the end.
This is not a test 1
[<]This is not[>] a test 2
This is not a test 3
This is not a test 4
From this I would like to send this text to external program. e.g:
:<some vim command>!<some shell command>
A solution that almost works is:
:[range]w ! cat | <some shell command>
This works for sending things linewise. For example:
:%w ! wc -l # produces --> '4'
:2,3w ! wc -l # produces --> '2'
:2w ! wc -w # produces --> '6'
However, using the example buffer above:
:'<,'>w ! wc -w # produces --> '6'
But I would like something that to produces '3' and does not affect the contents of the buffer.
Ideas?
select...
<esc>
:exe '!echo '.string(lh#visual#selection()).' | wc -w'
Seems to do the trick.
With lh#visual#selection()
coming from lh-vim-lib
A range is always linewise.
No matter what you do, every Ex command that accept a range will always take '<
as the start line and '>
as the end line.
Passing a non-linewise selection to an external program is done like this:
system()
and output the resultHere it is, in a function:
function! VisualCountWords() range
let n = @n
silent! normal gv"ny
echo "Word count:" . system("echo '" . @n . "' | wc -w")
let @n = n
" bonus: restores the visual selection
normal! gv
endfunction
that you can use in a mapping like this:
xnoremap <F6> :call VisualCountWords()<CR>
Also your use of cat is useless:
:[range]w ! cat | <some shell command>
should be:
:[range]w ! <some shell command>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With