¿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?

Me gustaría filtrar una selección visual en Vim a través de un comando. La forma en que sé filtra siempre las líneas completas sobre las que se extiende la selección visual:

Seleccionar 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

Considere las siguientes asignaciones que se adhieren al comportamiento del ! comandos de filtrado por líneas (ver :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

¡Muy bien! Lamento que mi pregunta no haya sido demasiado precisa (ídem kev). En realidad, estaba apuntando al caso más general en el que quiero hacer ambas cosas: 1) pasar la selección visual a un comando 2) especificar este comando en vim usando comandos cortos; es decir, el comando vim debe tomar 'base64 --decode' en su ejemplo como argumento. - chico alto

En otras palabras, debería hacer lo mismo que el comando de filtro, solo para la selección visual, no para las líneas completas. - chico alto

@user429540: Ahora veo. Eche un vistazo a la respuesta actualizada que enumera las asignaciones escritas en un intento de implementar esos comandos de filtrado. - ib.

¿Cómo lo llamo? :'<,'>,! echo (¿dónde está mi líder)? Para mí, todavía hace lo mismo como: '<,'>! echo (sin el líder). - chico alto

@user429540: Leader es una tecla configurable que es conveniente para crear asignaciones (ver :help mapleader); por defecto, es el carácter de barra invertida. Se supone que las asignaciones anteriores se deben usar de la misma manera que las predeterminadas ! filtrado: Seleccione un fragmento de texto en el modo Visual, luego presione la tecla principal (nuevamente, la barra invertida de forma predeterminada) seguida de !; o no seleccione nada, presione esta combinación de teclas, luego use un comando de movimiento (p. ej. w, W, ), etc). - ib.

Puedes usar \%V para hacer coincidir dentro del área Visual:

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

respondido 09 mar '12, 17:03

Gracias, esto funciona, es un poco largo sin embargo. ¿Cómo sería un vmap que toma el comando de shell como parámetro? - chico alto

.. y, por supuesto, en mi ejemplo, el comando no depende de la selección visual que, en general, puede ser el caso. Entonces, ¿cómo puedo pasar la selección visual como argumento al comando? - chico alto

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