¿Cómo insertar el resultado de un comando en el texto en vim?

42

Por ejemplo, :echo strftime(%c)mostrará la hora actual en la parte inferior, pero ¿cómo insertar esta cadena de tiempo en el texto (justo después del cursor)?

xzhu
fuente
1
Creo que el OP significa "¿Cómo insertar el resultado de una expresión Vim en el texto?"
Alastair Irvine
También vale la pena mencionar que esta no es la misma pregunta que Escribir una función vim para insertar un bloque de texto estático , sin embargo, algunas de las respuestas aún se aplican.
Alastair Irvine
Tu ejemplo es, literalmente, mi caso de uso y te saludo por ello.
Joe
Consulte también redireccionamiento a un registro: stackoverflow.com/questions/2573021/…
NeilG

Respuestas:

49

Puede usar el registro de expresión "=, con p(o P) en modo normal o <C-R>en modo inserción:

En modo normal:
( <C-M>aquí significa Control+ M, o simplemente presione Enter/ Return)

"=strftime('%c')<C-M>p

En modo de inserción:
( <C-M>tiene el mismo significado que el anterior, <C-R>significa Control+ R)

<C-R>=strftime('%c')<C-M>

Si desea insertar el resultado de la misma expresión muchas veces, es posible que desee asignarlos a las teclas en su .vimrc:
(aquí el <C-M>y <C-R>debe escribirse literalmente (una secuencia de cinco caracteres imprimibles: Vim los traducirá internamente))

:nmap <F2> "=strftime('%c')<C-M>p
:imap <F2> <C-R>=strftime('%c')<C-M>
Chris Johnsen
fuente
2
+1 ¡Por supuesto! El "=registro : - /
Eelvex
2
para obtener el valor de una variable vim (por ejemplo, opciones de sesión): ¡ <C-R>=&sessionoptionsincluso completa la pestaña de modo salvaje!
Justin M. Keyes
2
: put = strftime ('% c') <CM>
brunch875
En el modo de inserción, el uso <c-r>=es lento para el comando, que puede tener mucha salida y también puede romper la sangría para que el texto de salida sea ilegible. Por ejemplo, <c-r>=execute('nmap')la salida se escribirá línea por línea, lo cual es muy lento.
jdhao
22

:r!date +\%c

ver :help :r!

Glenn Jackman
fuente
1
datees un comando externo y !llama a comandos externos mientras OP solicita los comandos vim.
Eelvex
@eelvex no, no lo hizo. y el ! es un comando vim y vi. Este es el método canónico. Funciona para muchas otras cosas también.
Keith
55
@Keith: yes !es un comando vi (m) que llama a comandos externos . Puede tener razón OP no queriendo generar solo comandos vim pero si lo hace, !no lo hará.
Eelvex
11

Estos comandos insertarán la salida de la strftime("%c")derecha donde está el cursor:

:exe ":normal i" . strftime("%c")

y

:call feedkeys("i". strftime("%c"))

Hay otras formas de hacer lo que quieras (como, por ejemplo, las de la respuesta de Mikel ).

Editar : Aún mejor, para insertar en el lugar, use el =registro como describe Chris Johnsen

Eelvex
fuente
10

Si desea insertar la salida de un comando vim (a diferencia del valor de retorno de una llamada de función ), debe capturarlo. Esto se logra a través del :redircomando, que le permite redirigir el equivalente de vim de la salida estándar a una variable, archivo, registro u otro objetivo.

:redires dolorosamente inconveniente de usar; Escribiría una función para encapsular su funcionalidad de una manera más conveniente, algo así como

funct! Exec(command)
    redir =>output
    silent exec a:command
    redir END
    return output
endfunct!

Una vez que haya declarado dicha función, puede usar el registro de expresión (como explicó Chris Johnsen) para insertar la salida de un comando en la posición del cursor. Entonces, desde el modo normal, presione i^R=Exec('ls')para insertar la lista de los búferes actuales de vim.

Tenga en cuenta que el comando se ejecutará en el espacio de nombres de la función, por lo que si utiliza una variable global, tendrá que explícitamente asignarle un espacio de nombres con el prefijo g:. También tenga en cuenta que Exec(), como se escribió anteriormente, agregará una nueva línea de terminación incluso a la salida de una línea. Es posible que desee agregar una llamada a substitute()la función para evitar esto.

Consulte también https://stackoverflow.com/questions/2573021/vim-how-to-redirect-ex-command-output-into-current-buffer-or-file/2573054#2573054 para obtener más información sobre rediry un enlace a Un comando relacionado.

intuido
fuente
2
Esto funciona muy bien. Agregué un set pastecomando antes de devolver la salida y un set nopastedespués, para evitar la sangría de la escalera cuando las líneas comienzan con espacios en blanco. En realidad, quería guardar el valor de la opción de pegar actual y devolverlo, pero no pude hacerlo.
Juan Lanus
1
@JuanLanus The set nopasteno debería funcionar después return output, porque la declaración return es un punto de salida fuera de la función. He puesto mi solución a este problema como una respuesta separada en esta página.
Evgeni Sergeev
4
:call append(line('.'), strftime("%c"))

Lo colocará en la siguiente línea, luego puede presionar J( Shift+ J) para unirlo a la posición actual.

O si lo necesita todo en un solo comando, podría hacer

:call setline(line('.'), getline(line('.')) . strftime("%c"))

o

:call setline(line('.'), getline(line('.')) . " " . strftime("%c"))

dependiendo de si desea insertar un espacio antes de la fecha o no.

Mikel
fuente
4

Mejorando la respuesta @intuited para evitar el problema con espacios en blanco líderes y sangría creciente:

"Examples:
":call Exec('buffers')
"This will include the output of :buffers into the current buffer.
"
"Also try:
":call Exec('ls')
":call Exec('autocmd')
"
funct! Exec(command)
    redir =>output
    silent exec a:command
    redir END
    let @o = output
    execute "put o"
    return ''
endfunct!

Esto simplemente se insertará en la ubicación actual del archivo cuando salga :call Exec('command')del modo normal. Como se señaló en el comentario , el =Exec('command')enfoque Ctrl + R original (modo de inserción) con la Exec(..)devolución de una cadena podría corregirse parcialmente mediante el uso set paste, pero no ofrece la oportunidad de colocarlo en set nopastecualquier lugar.

La let @o = outputsintaxis establece el registro oen el contenido de la variable output, como se explica aquí: https://stackoverflow.com/a/22738310/1143274

La return ''línea es para que el valor de retorno predeterminado de 0no se inserte en el búfer.

Evgeni Sergeev
fuente
2

Así es como lo hago. Lo coloca justo después del cursor porque lo usa p.

" save previous yank
let reg_save = @@

" save your text to the '@' register
let @@ = strftime('%c')
" paste it after the cursor
exec "normal! p"

" restore previous yank
let @@ = reg_save
Juan Ibiapina
fuente