Come si può spostare il testo da un registro a un numero arbitrario di registri?


10

Esiste un modo per "reindirizzare" il testo da un registro a un altro registro o set di registri? Ad esempio, passa "qa registri "1attraverso "5.

Vorrei spesso creare versioni leggermente diverse della stessa macro, quindi è utile essere in grado di copiare una macro "modello" su più registri e quindi modificarne ognuna in posizione.

Per fare un esempio pratico, ecco il problema che mi ha posto questa domanda.

Devo trasformare la seguente riga da un linguaggio di descrizione hardware in molti blocchi ripetuti,

RAM64(in=in, load=load0, address=address[0..5], out=out1);

per

RAM64(in=in, load=load1, address=address[0..5], out=out2);
RAM64(in=in, load=load2, address=address[0..5], out=out3);
RAM64(in=in, load=load3, address=address[0..5], out=out4);
RAM64(in=in, load=load4, address=address[0..5], out=out5);

Ho una macro che esegue questo, usando la funzione di incremento, yypW^At)^Ache ho memorizzato nel registro "a.

A volte, ho bisogno che il modello di incremento sia leggermente diverso, come ad esempio

RAM512(in=in, load=load1, address=address[0..8], out=out2);
RAM512(in=in, load=load2, address=address[0..8], out=out4);
RAM512(in=in, load=load3, address=address[0..8], out=out6);
RAM512(in=in, load=load4, address=address[0..8], out=out8);

dove "bsarebbe la macro nel registro yypW^At)^A^A.

Voglio un registro per fare questo, ma per ogni incremento da 1-5. Il registro "apotrebbe (in qualche modo) essere copiato nei registri da b a e. Quindi incollerei ogni registro nel buffer, apporterei la modifica richiesta (aggiungere più termini, cambiare il carattere che segue il tmovimento ecc.) E riportare l'espressione modificata nel registro. Idealmente, questo ultimo passaggio potrebbe anche essere incluso nei comandi per copiare i registri

Questo mi evita di ripetere tutti i caratteri nella macro che NON richiedono modifiche. Per il mio esempio può essere banale, ma posso prevedere momenti in cui potrebbe essere molto utile fare ciò che sto chiedendo.


5
A parte questo, non consiglierei di usare i registri numerati. Gli unici registri "sicuri" sono i registri alfabetici. Tutti gli altri registri vengono impostati automaticamente da Vim.
Jamessan,

Risposte:


7

Le macro sono solo testo.

Apri un nuovo buffer vuoto e inserisci lì la tua macro. Puoi duplicare le linee, cambiare una cosa qui e qualcos'altro altrove quindi strappare una linea e usarla subito @".

Non è necessario inquinare i registri, in particolare i registri numerici che hanno uno scopo completamente diverso.

-- modificare --

La tua domanda è più facile da capire ora che hai aggiunto qualche spiegazione.

A quanto pare, devi solo cambiare la registrazione iniziale per raggiungere il tuo obiettivo, senza giocare con i registri come se fossero variabili:

:let i = 1                     " define variable i
qa                             " start recording in register a
yy                             " yank the line
p                              " paste it
W                              " move to next WORD
<C-v><C-a>                     " increment number
t)                             " jump to the other number to increment
:norm <C-r>=i<CR><C-v><C-a>    " increment the number by i
q                              " stop recording

Per creare 5 copie della riga corrente con l'ultimo numero incrementato di 2:

:let i = 2|norm 5@a

o 12 copie, con l'ultimo numero incrementato di 23:

:let i = 23|norm 12@a

Concordato sui registri numerici, ma cosa succede se si desidera utilizzarlo in un comando e sono necessari registri che iniziano allo stesso modo ma diventano diversi?
mercoledì

@WChargin, per favore, spiega.
romainl

Come in, forse, voglio fare qualcosa con copie ruotate di una stringa, quindi se abcdesi trova in @q, allora voglio @x="bcdea", @y="abcde"e @z="eabcd". Potrei iniziare lasciando @x, @ye @ztutti uguali a @qe poi modificandoli secondo necessità. Ovviamente, l'ho appena inventato, ma sembra che ci possano essere alcuni casi in cui qualcosa di simile potrebbe essere utile.
mercoledì

2
@Kit, sono un po 'preoccupato per la mancanza di un esempio pratico nella tua domanda che lo rende immediatamente odore di XY. Sono quasi certo che stai abusando dei registri, quindi mi piacerebbe leggere una spiegazione di ciò che stai cercando di fare.
romainl

1
@Kit, questo è uno dei tanti problemi con le domande sul problema XY. La risposta più votata è una risposta diretta di alta qualità alla tua domanda, ma alla fine inutile nel contesto del tuo vero problema, mentre la mia risposta meno votata è una soluzione effettiva al tuo problema di fondo. Entrambe le risposte sono corrette ma rispondono a domande diverse che ti rendono difficile decidere. Se fossi in me, accetterei la risposta che affronta il mio problema principale ... ma sono solo io.
romainl

6

Utilizzando getregesetreg

Per copiare da qai registri 1- 5:

let src=getreg('q', 1)
for i in range(1, 5)
    call setreg(i, src)
endfor

Per copiare in un elenco più generale:

let src=getreg('q', 1)
for i in ['a', 'c', 'e']
    call setreg(i, src)
endfor

utilizzando execute

Per copiare da qai registri 1- 5:

for i in range(1, 5)
   execute 'let @' . i . '=@a'
endfor

Per copiare in un elenco più generale:

for i in ['a', 'c', 'e']
    execute 'let @' . i . '=@a'
endfor

Spiegazione. Il comando letpuò essere usato come let @x=@y, quali copie registrano yper registrarsi x. In sostanza, stiamo solo costruendo questi comandi in un ciclo (modificando il valore di xnella forma sopra) e executeinserendoli.


1
Non è necessario utilizzare :exequi. Le funzioni getreg()e setreg()sarebbero più pulite.
Jamessan,

@jamessan Bel suggerimento, grazie: sto usando questi correttamente?
mercoledì

L'ho modificato per aggiungere il secondo argomento opzionale a getreg () poiché restituisce il contenuto del registro anziché una possibile valutazione di esso.
Jamessan,

1

Per rispondere direttamente alla domanda, se si desidera copiare rapidamente e facilmente i contenuti di un registro in un altro, è possibile inserire quanto segue nel proprio .vimrc. È quindi possibile eseguire <leader>rcabper copiare il contenuto del registro aper registrarsi b. Come esempio ho scelto <leader>rcdi indicare 'copia copia'

function! s:CopyRegister()
    let sourceReg = nr2char(getchar())

    if sourceReg !~# '\v^[a-z0-9]'
        echo "Invalid register given: " . sourceReg
        return
    endif

    let destinationReg = nr2char(getchar())

    if destinationReg !~# '\v^[a-z0-9]'
        echo "Invalid register given: " . destinationReg
        return
    endif

    call setreg(destinationReg, getreg(sourceReg, 1))
    echo "Replaced register '". destinationReg ."' with contents of register '". sourceReg ."'"
endfunction

" rc = register copy
nnoremap <leader>rc :call <sid>CopyRegister()<cr>

1
Lo consiglierei getreg(sourceReg, 1).
Jamessan,

Ah sì, vero. Fisso.
Steve Vermeulen,
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.