Come redirect l’output del comando ex nel buffer o nel file corrente?

Come posso redirect o redirect l’output di un comando ex nel mio buffer corrente o in un file?

Ad esempio, voglio leggere il contenuto di tutti i registri nel buffer corrente, che in modalità ex viene mostrato usando :registers .

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

L’ultimo comando è molto utile, dal momento che ci sono molte opzioni per il reindirizzamento: alle variabili, ai registri, come aggiungere, ulteriore cornucopia.

Trovo ancora strano e fastidioso che usi END in questo modo, ma poiché tutto ciò che può seguire redir deve iniziare con un carattere non di parole, almeno non è ambiguo.

PS AFAIK (che è piuttosto lontano in questo caso) non c’è modo di leggerlo direttamente nel buffer: devi prima memorizzarlo in un registro o in una variabile. Controlla l’aiuto per le varie opzioni su come farlo.

PPS Se vuoi farlo usando una variabile – forse per incapsularla in una funzione ed evitare i registri di clobbering o le variabili globali – devi convertire la stringa multilinea che viene scritta nella variabile in una lista. PER ESEMPIO

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

Altrimenti (se si fa semplicemente append('.',var) ) si finisce con ^ @ ‘s (null) invece di newline, poiché questo è ciò che vimscript usa per rappresentare le newline nelle variabili String.

edit : come @Bill menziona Odom, usando :put =variable_you_redirected_to è molto più semplice dell’espressione complicata append() . Grazie, Bill!


PPPS

Ho scritto uno snippet per rendere questa roba più comoda. Dichiara una funzione Redir(command, target) e un comando R

Il comando analizza l’ultima serie di caratteri non spaziali come destinazione di reindirizzamento e passa alla funzione, che esegue il boilerplate per redirect l’output del comando al target di reindirizzamento.

Il comando è tutto dopo R e prima dell’ultimo spazio.

PER ESEMPIO

 " 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() @"> 

Ci sono alcune limitazioni con questo: per esempio non sarai in grado di scrivere su un nome di file che contiene uno spazio. Il vantaggio di questo è che non devi citare il tuo comando. L’ho pubblicato su gist.github.com, e cercherò di tenerlo aggiornato se finisco per migliorarlo. Oppure puoi lanciarlo da solo !

Ad ogni modo lo snippet è disponibile qui . Può essere inserito in un file .vimrc o in un file in ~ / .vim / plugins.

@intuited ha ragione; il comando redir è quello che vuoi. Un one-liner come questo inserirà l’output di: registers nel buffer corrente:

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

Non è qualcosa che vorrete digitare molto spesso, tuttavia, e non è esattamente adatto a una mappa chiave. Mi sono trovato a farlo abbastanza spesso, così ho scritto una funzione e una manciata di comandi per renderlo più facile. Come bonus, ora posso inviare l’output del comando a una nuova finestra o nuova scheda con la stessa facilità con cui lo si inserisce nel buffer corrente. Ecco il codice (con alcuni esempi di comandi alla fine):

 " 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 reindirizza tutti i messaggi da qui in un registro chiamato a . Lo segui con il tuo comando di cui vuoi acquisire l’output ( :registers nel tuo caso). :redir END termina il reindirizzamento. "ap significa "a , "a utilizza il registro denominato a e p mette il contenuto del registro selezionato nel buffer corrente.

Vedi Capture ex command output su Vim Tips Wiki per maggiori informazioni 🙂

Non è necessario utilizzare una variabile temporanea finché è ansible salvare il buffer corrente e va bene aggiungendo i messaggi alla fine del file corrente.

Dalla documentazione di 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

Quindi, per aggiungere i messaggi da :registers in fondo al file corrente, fai questo:

 :write | redir >> % | silent registers | redir END | edit 
  1. :write il file in modo che eventuali modifiche non andranno perse
  2. Iniziare a redirect l’output su % , il nome del file corrente.
  3. Esegui silenziosamente il comando :registers .
  4. END redirect al file.
  5. :edit il file per vedere le nuove modifiche.

Puoi anche forzatamente troncare il file corrente e sostituirlo con i messaggi di output:

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

Ma probabilmente non è quello che vuoi fare.

Inoltre :h :redir :

… Per ottenere l’output di un comando, | execute () | la funzione può essere utilizzata.

per esempio

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

Sfortunatamente non ho rappresentanti, quindi non posso aggiungere questo come commento a “Francis Niu”.

La funzione execute() sembra il modo più semplice per farlo, ed è stata aggiunta in vim 8 .

Elencato nelle nuove / estese funzionalità del github di vim. version8.txt