¿Cómo filtrar el contenido de una selección visual que no abarca una línea completa a través de un comando externo en 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:

Selección a test en la línea de

this is a test

y escribiendo

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

resultará en

the result

Pero yo quiero:

this is the result

preguntado el 09 de marzo de 12 a las 16:03

2 Respuestas

Consider the following mappings that adhere the behavior of the ! linewise filtering commands (see :helpg \*!\* y :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

Respondido 26 Abr '12, 04:04

Very good! Sorry that my question was not too precise (ditto kev). It was actually targeting the most general case in which I want to do both: 1) pass the visual selection to a command 2) specify this command in vim using short commands; i.e. the vim command should take the 'base64 --decode' in your example as an argument. - chico alto

In other words it should effectively do the same as the filter command !, just for the visual selection only, not complete lines. - chico alto

@user429540: Now I see. Take a look at the updated answer listing the mappings written in attempt to implement that filtering commands. - ib.

How do I call it? :'<,'>,! echo (where , is my leader)? For me it still does the same thing like :'<,'>! echo (without the leader). - chico alto

@user429540: Leader is a configurable key which is convenient for creating mappings (see :help mapleader); by default, it is the backslash character. The mappings above are supposed to be used the same way as default ! filtering: Select a piece of text in Visual mode, then press your leader key (again, backslash by default) followed by !; or do not select anything, press this key combination, then use a motion command (e.g. w, W, ), etc). - ib.

Puede usar el \%V to match inside the Visual area:

:'<,'>s/\%V.*\%V/\=system('echo -n "the result"')

respondido 09 mar '12, 17:03

Thanks, this works, is a little long however. What would a vmap lookk like which takes the shell command as parameter? - chico alto

.. and of course in my example the command does not depend on the visual selection which can in general be the case. So how can I pass the visual selection as argument to the command? - chico alto

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.