Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to filter the contents of a Visual selection that does not span an entire line through an external command in Vim?

Tags:

vim

I would like to filter a visual selection in Vim through a command. The way I know filters always the complete lines over which the visual selection extends:

Selecting a test in the line

this is a test

and typing

:'<,'>!echo "the result"

will result in

the result

But I want:

this is the result
like image 754
highsciguy Avatar asked Mar 09 '12 16:03

highsciguy


2 Answers

Consider the following mappings that adhere the behavior of the ! linewise filtering commands (see :helpg \*!\* and :help v_!).

nnoremap <silent> <leader>! :set opfunc=ProgramFilter<cr>g@
vnoremap <silent> <leader>! :<c-u>call ProgramFilter(visualmode(), 1)<cr>
function! ProgramFilter(vt, ...)
    let [qr, qt] = [getreg('"'), getregtype('"')]
    let [oai, ocin, osi, oinde] = [&ai, &cin, &si, &inde]
    setl noai nocin nosi inde=

    let [sm, em] = ['[<'[a:0], ']>'[a:0]]
    exe 'norm!`' . sm . a:vt . '`' . em . 'x'

    call inputsave()
    let cmd = input('!')
    call inputrestore()

    let out = system(cmd, @")
    let out = substitute(out, '\n$', '', '')
    exe "norm!i\<c-r>=out\r"

    let [&ai, &cin, &si, &inde] = [oai, ocin, osi, oinde]
    call setreg('"', qr, qt)
endfunction
like image 180
ib. Avatar answered Oct 31 '22 15:10

ib.


You can use \%V to match inside the Visual area:

:'<,'>s/\%V.*\%V/\=system('echo -n "the result"')
like image 34
kev Avatar answered Oct 31 '22 14:10

kev