¿Cómo redirigir la salida del comando ex al búfer o archivo actual?

¿Cómo puedo redirigir o canalizar la salida de un comando ex en mi búfer actual o un archivo?

Por ejemplo, quiero leer el contenido de todos los registros en el búfer actual, que en modo ex se muestra usando :registers .

 :redir >name_of_registers_file :registers :redir END :r name_of_registers_file :help redir 

El último comando es muy útil, ya que hay muchas opciones para la redirección: a las variables, a los registros, cómo anexar, más cornucopia.

Todavía me parece extraño y molesto que use END de esa manera, pero ya que todo lo demás que puede seguir a redir tiene que comenzar con un carácter no de palabra, al menos no es ambiguo.

PS AFAIK (que es bastante lejos en este caso) no hay forma de leerlo directamente en el búfer: primero debe almacenarlo en un registro o una variable. Consulte la ayuda para ver las diferentes opciones de cómo hacerlo.

PPS Si desea hacer esto usando una variable -posiblemente para encapsularla en una función y evitar los registros irrecuperables o las variables globales-, deberá convertir la cadena de línea múltiple que se escribe en la variable en una lista. P.EJ

 :call append( '.', split(variable_you_redirected_to, "\n") ) 

De lo contrario (si solo append('.',var) ) terminas con ^ @ ‘s (nulls) en lugar de nuevas líneas, ya que es lo que vimscript usa para representar nuevas líneas en las variables String.

editar : como @Bill Odom menciona, usar :put =variable_you_redirected_to es mucho más fácil que la complicada expresión append() . Gracias, Bill!


PPPS

He escrito un fragmento para que esto sea más conveniente. Declara una función Redir(command, target) y un comando R

El comando analiza la última serie de caracteres que no son de espacio como un objective de redireccionamiento y lo pasa a la función, que hace el texto repetitivo para redirigir la salida del comando al objective de redireccionamiento.

El comando es todo después de R y antes del último espacio.

P.EJ

 " Store the vim buffer list in buffer_list.txt :R ls >buffer_list.txt " Store error messages emitted by a function being debugged " in the 'unnamed register' :R call FunctionBeingDebugged() @"> 

Hay algunas limitaciones con esto: por ejemplo, no podrá escribir en un nombre de archivo que contenga un espacio. Lo bueno de esto es que no tienes que citar tu comando. Lo tengo publicado en gist.github.com, y trataré de mantenerlo actualizado si termino mejorando. O puede bifurcarse usted mismo !

De todos modos, el fragmento está disponible aquí . Se puede soltar en un archivo .vimrc o en un archivo en ~ / .vim / plugins.

@intuited tiene razón; el comando redir es lo que quieres. Una línea como esta insertará la salida de: registers en el búfer actual:

 redir => m | silent registers | redir END | put=m 

Sin embargo, eso no es algo que quieras escribir muy a menudo, y no es exactamente compatible con un mapa clave. Me encontré haciendo esto con bastante frecuencia, así que escribí una función y un puñado de comandos para hacerlo más fácil. Como extra, ahora puedo enviar salida de comando a una nueva ventana o pestaña nueva tan fácilmente como insertarla en el búfer actual. Aquí está el código (con algunos ejemplos de comandos al final):

 " redir_messages.vim " " Inspired by the TabMessage function/command combo found " at . " function! RedirMessages(msgcmd, destcmd) " " Captures the output generated by executing a:msgcmd, then places this " output in the current buffer. " " If the a:destcmd parameter is not empty, a:destcmd is executed " before the output is put into the buffer. This can be used to open a " new window, new tab, etc., before :put'ing the output into the " destination buffer. " " Examples: " " " Insert the output of :registers into the current buffer. " call RedirMessages('registers', '') " " " Output :registers into the buffer of a new window. " call RedirMessages('registers', 'new') " " " Output :registers into a new vertically-split window. " call RedirMessages('registers', 'vnew') " " " Output :registers to a new tab. " call RedirMessages('registers', 'tabnew') " " Commands for common cases are defined immediately after the " function; see below. " " Redirect messages to a variable. " redir => message " Execute the specified Ex command, capturing any messages " that it generates into the message variable. " silent execute a:msgcmd " Turn off redirection. " redir END " If a destination-generating command was specified, execute it to " open the destination. (This is usually something like :tabnew or " :new, but can be any Ex command.) " " If no command is provided, output will be placed in the current " buffer. " if strlen(a:destcmd) " destcmd is not an empty string silent execute a:destcmd endif " Place the messages in the destination buffer. " silent put=message endfunction " Create commands to make RedirMessages() easier to use interactively. " Here are some examples of their use: " " :BufMessage registers " :WinMessage ls " :TabMessage echo "Key mappings for Control+A:" | map  " command! -nargs=+ -complete=command BufMessage call RedirMessages(, '' ) command! -nargs=+ -complete=command WinMessage call RedirMessages(, 'new' ) command! -nargs=+ -complete=command TabMessage call RedirMessages(, 'tabnew' ) " end redir_messages.vim 
 :redir @a :registers :redir END "ap 

:redir @a redirige todos los mensajes desde aquí a un registro llamado a . Siga esto con su comando cuyo resultado desea capturar ( :registers en su caso). :redir END finaliza la redirección. "ap significa "a , "a usa el registro llamado a y p pone los contenidos del registro seleccionado en el búfer actual.

Vea la salida del comando Capture ex en Vim Tips Wiki para más información 🙂

No es necesario utilizar una variable temporal, siempre que pueda guardar el búfer en uso y acepte adjuntar los mensajes al final del archivo actual.

De la documentación de Vim:

 :redi[r] >> {file} Redirect messages to file {file}. Append if {file} already exists. {not in Vi} 

http://vimdoc.sourceforge.net/htmldoc/various.html#:redir

Por lo tanto, para anexar los mensajes de :registers al final del archivo actual, haga esto:

 :write | redir >> % | silent registers | redir END | edit 
  1. :write el archivo para que no se pierda ningún cambio
  2. Comience a redirigir la salida a % , el nombre del archivo actual.
  3. Ejecute silenciosamente el comando :registers .
  4. END redirecciona al archivo.
  5. :edit el archivo para ver los nuevos cambios.

También puede truncar con fuerza el archivo actual y reemplazarlo con los mensajes de salida:

 :redir! > % | silent registers | redir END | edit! 

Pero eso probablemente no es lo que quieres hacer.

Además :h :redir :

… Para obtener la salida de un comando, | execute () | función puede ser utilizada.

p.ej

 put = execute('scriptnames') put = execute('filter /vimfiles/ scriptnames') 

Lamentablemente no tengo representante, por lo que no puedo agregar esto como un comentario a ‘Francis Niu’.

La función execute() parece la forma más fácil de lograr esto, y se agregó en vim 8 .

Incluido en las características nuevas / extendidas en vim’s github. version8.txt