Come inserire il risultato di un comando nel testo in vim?


42

Ad esempio, :echo strftime(%c)mostrerà l'ora corrente in basso, ma come inserire questa stringa di tempo nel testo (subito dopo il cursore)?


1
Credo che OP significhi "Come inserire il risultato di un'espressione di Vim nel testo?"
Alastair Irvine,

Vale anche la pena ricordare che questa non è la stessa domanda di Scrivere una funzione vim per inserire un blocco di testo statico , tuttavia alcune delle risposte si applicano ancora.
Alastair Irvine,

Il tuo esempio è letteralmente il mio caso d'uso e ti saluto.
Joe,

Vedere anche riorientare in un registro: stackoverflow.com/questions/2573021/...
NeilG

Risposte:


49

È possibile utilizzare il registro delle espressioni "=, con p(o P) in modalità normale o <C-R>in modalità inserimento:

In modalità normale:
( <C-M>qui significa Control+ M, oppure basta premere Enter/ Return)

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

In modalità insert:
( <C-M>ha lo stesso significato di cui sopra, <C-R>significa Control+ R)

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

Se vuoi inserire più volte il risultato della stessa espressione, allora potresti voler mapparli su chiavi nel tuo .vimrc:
(qui il <C-M>e <C-R>dovrebbe essere digitato letteralmente (una sequenza di cinque caratteri stampabili - Vim li tradurrà internamente))

:nmap <F2> "=strftime('%c')<C-M>p
:imap <F2> <C-R>=strftime('%c')<C-M>

2
+1 Fuori rotta! Il "=registro. : - /
Eelvex,

2
per ottenere il valore di una variabile vim (ad esempio, sessionoptions): <C-R>=&sessionoptions- esegue anche il completamento con tab wildmode!
Justin M. Keyes,

2
: put = strftime ('% c') <CM>
brunch875

Nella modalità di inserimento, l'uso <c-r>=è lento per il comando che può avere un sacco di output e può anche rompere il rientro in modo che il testo di output sia illeggibile. Ad esempio, <c-r>=execute('nmap')l'output verrà scritto riga per riga, il che è molto lento.
jdhao,

22

:r!date +\%c

vedere :help :r!


1
dateè un comando esterno e !chiama comandi esterni mentre OP richiede comandi vim.
Eelvex,

@eelvex no non l'ha fatto. e il ! è un comando vim e vi. Questo è il metodo canonico. Funziona anche per molte altre cose.
Keith,

5
@Keith: yes !è un comando vi (m) che chiama comandi esterni . Potresti avere ragione OP non voler emettere solo i comandi vim ma se lo fa, !non lo farà.
Eelvex,

11

Questi comandi inseriranno l'output di strftime("%c")destra nel punto in cui si trova il cursore:

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

e

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

Esistono altri modi per fare ciò che vuoi (come, ad esempio, quelli sulla risposta di Mikel ).

Modifica : ancora meglio, per l'inserimento sul posto, utilizzare il =registro come descritto da Chris Johnsen


10

Se si desidera inserire l'output di un comando vim (al contrario del valore restituito di una chiamata di funzione ), è necessario acquisirlo. Ciò si ottiene tramite il :redircomando, che consente di reindirizzare l'equivalente di Vim dell'output standard in una variabile, un file, un registro o un'altra destinazione.

:redirè dolorosamente scomodo da usare; Scriverei una funzione per incapsulare la sua funzionalità in un modo più conveniente, qualcosa del genere

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

Dopo aver dichiarato tale funzione, è possibile utilizzare il registro delle espressioni (come spiegato da Chris Johnsen) per inserire l'output di un comando nella posizione del cursore. Quindi, dalla modalità normale, premi i^R=Exec('ls')per inserire l'elenco dei buffer correnti di vim.

Tenere presente che il comando verrà eseguito nello spazio dei nomi delle funzioni, quindi se si utilizza una variabile globale, sarà necessario specificarlo nello spazio prefissandolo con il prefisso g:. Si noti inoltre che Exec(), come scritto sopra, verrà aggiunta una nuova riga finale anche all'output di una riga. Potresti voler aggiungere una chiamata alla substitute()funzione per evitarlo.

Vedi anche https://stackoverflow.com/questions/2573021/vim-how-to-redirect-ex-command-output-into-current-buffer-or-file/2573054#2573054 per maggiori informazioni su redire un link a un comando correlato.


2
Funziona benissimo. Ho aggiunto un set pastecomando prima di restituire l'output e un set nopastedopo, per evitare il rientro della scala quando le linee iniziano con gli spazi. In realtà, volevo salvare il valore dell'opzione incolla corrente e restituirlo, ma non sono riuscito a farlo.
Juan Lanus,

1
@JuanLanus Non set nopastedovrebbe funzionare dopo return output, perché l'istruzione return è un punto di uscita fuori dalla funzione. Ho inserito la mia soluzione a questo problema come risposta separata in questa pagina.
Evgeni Sergeev,

4
:call append(line('.'), strftime("%c"))

Lo metterà sulla riga successiva, quindi potresti premere J( Shift+ J) per unirlo alla posizione corrente.

O se hai bisogno di tutto in un solo comando, puoi farlo

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

o

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

a seconda che si desideri inserire uno spazio prima della data o meno.


4

Migliorare la risposta @intuited per evitare il problema con i principali spazi bianchi e il rientro crescente:

"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!

Questo verrà semplicemente inserito nella posizione corrente nel file quando si :call Exec('command')passa dalla modalità normale. Come notato nel commento , l' =Exec('command')approccio originale (insert-mode) Ctrl + R con la Exec(..)restituzione di una stringa potrebbe essere parzialmente corretto usando set paste, ma non offre l'opportunità di mettere set nopasteovunque.

La let @o = outputsintassi imposta il registro osul contenuto della variabile output, come spiegato qui: https://stackoverflow.com/a/22738310/1143274

La return ''linea è in modo che il valore di ritorno predefinito di 0non venga inserito nel buffer.


2

Questo è come lo faccio. Lo mette subito dopo il cursore perché 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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.