Wie kann Text von einem Register in eine beliebige Anzahl von Registern verschoben werden?


10

Gibt es eine Möglichkeit, Text von einem Register in ein anderes Register oder einen anderen Registersatz zu leiten? Bewegen Sie sich beispielsweise "qzu Registern "1durch "5.

Ich möchte oft leicht unterschiedliche Versionen desselben Makros erstellen, daher ist es nützlich, ein 'Vorlagen'-Makro in mehrere Register kopieren und dann jedes an Ort und Stelle ändern zu können.

Um ein praktisches Beispiel zu geben, hier ist das Problem, das diese Frage für mich ausgelöst hat.

Ich muss die folgende Zeile aus einer Hardwarebeschreibungssprache in viele wiederholte Blöcke umwandeln:

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

zu

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);

Ich habe ein Makro, das dies mit der Inkrementfunktion ausführt, yypW^At)^Adie ich im Register gespeichert habe "a.

Manchmal muss das Inkrementierungsmuster etwas anders sein, z

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);

wo das Makro im Register "bwäre yypW^At)^A^A.

Ich möchte, dass ein Register dies tut, aber für jedes Inkrement von 1-5. Das Register "akönnte (irgendwie) in die Register b bis e kopiert werden. Dann würde ich jedes Register in den Puffer einfügen, die erforderliche Änderung vornehmen (weitere Begriffe hinzufügen, das Zeichen ändern, das der tBewegung folgt usw.) und den geänderten Ausdruck zurück in das Register ziehen. Idealerweise könnte dieser letzte Schritt sogar in den Befehlen zum Kopieren der Register enthalten sein

Dies erspart mir das Wiederholen aller Zeichen im Makro, die NICHT geändert werden müssen. Für mein Beispiel mag es trivial sein, aber ich kann Zeiten vorhersehen, in denen es sehr hilfreich sein könnte, das zu tun, was ich verlange.


5
Abgesehen davon würde ich nicht empfehlen, die nummerierten Register zu verwenden. Die einzigen "sicheren" Register sind die alphabetischen Register. Alle anderen Register werden automatisch von Vim eingestellt.
Jamessan

Antworten:


7

Makros sind nur Text.

Öffnen Sie einen neuen leeren Puffer und platzieren Sie Ihr Makro dort. Sie können die Zeilen duplizieren, eine Sache hier und etwas anderes an anderer Stelle ändern, dann eine Zeile ziehen und sie sofort mit verwenden @".

Sie müssen Ihre Register nicht verschmutzen, insbesondere nicht die Nummernregister, die einem ganz anderen Zweck dienen.

- bearbeiten -

Ihre Frage ist jetzt leichter zu verstehen, da Sie eine Erklärung hinzugefügt haben.

Wie sich herausstellt, müssen Sie nur Ihre ursprüngliche Aufzeichnung ändern, um Ihr Ziel zu erreichen, ohne mit Registern zu spielen, als wären sie Variablen:

: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

So erstellen Sie 5 Kopien der aktuellen Zeile mit der letzten um 2 erhöhten Nummer:

:let i = 2|norm 5@a

oder 12 Exemplare, wobei die letzte Zahl um 23 erhöht wurde:

:let i = 23|norm 12@a

Einverstanden über die numerischen Register - aber was ist, wenn Sie dies in einem Befehl verwenden möchten und Register benötigen, die gleich beginnen, aber unterschiedlich werden?
wchargin

@WChargin, bitte erklären.
Romainl

Wie in, vielleicht will ich etwas mit gedrehten Kopien einer Zeichenfolge tun, also wenn abcdein ist @q, dann will ich @x="bcdea", @y="abcde"und @z="eabcd". Ich könnte , indem wir beginnen @x, @yund @zalle gleich @qund ändern sie dann je nach Bedarf. Natürlich habe ich mir das nur ausgedacht, aber es scheint, dass es einige Fälle gibt, in denen etwas Ähnliches nützlich sein könnte.
wchargin

2
@Kit, ich bin ein bisschen besorgt über das Fehlen eines praktischen Beispiels in Ihrer Frage, wodurch es sofort nach XY riecht. Ich bin mir fast sicher, dass Sie Register missbrauchen, daher würde ich gerne eine Erklärung darüber lesen, was Sie versuchen zu tun.
Romainl

1
@ Kit, das ist eines der vielen Probleme mit XY-Problemstellungen. Die am besten bewertete Antwort ist eine qualitativ hochwertige direkte Antwort auf Ihre Frage, die jedoch im Kontext Ihres eigentlichen Problems letztendlich nutzlos ist, während meine weniger positiv bewertete Antwort eine tatsächliche Lösung für Ihr zugrunde liegendes Problem darstellt. Beide Antworten sind richtig, beantworten jedoch unterschiedliche Fragen, was Ihnen die Entscheidung erschwert. Wenn ich es wäre, würde ich die Antwort akzeptieren, die mein Kernproblem anspricht… aber das bin nur ich.
Romainl

6

Verwenden von getregundsetreg

So kopieren Sie von qin Register 1- 5:

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

So kopieren Sie in eine allgemeinere Liste:

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

Verwenden von execute

So kopieren Sie von qin Register 1- 5:

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

So kopieren Sie in eine allgemeinere Liste:

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

Erläuterung. Der Befehl letkann als verwendet werden let @x=@y, um Register yzu Register zu kopieren x. Im Wesentlichen konstruieren wir diese Befehle nur in einer Schleife (ändern den Wert von xin der obigen Form) und geben executesie ein.


1
Hier besteht keine Notwendigkeit zu verwenden :exe. Die getreg()und setreg()Funktionen wären sauberer.
Jamessan

@jamessan Netter Vorschlag, danke - verwende ich diese richtig?
Wchargin

Ich habe es bearbeitet, um das optionale zweite Argument zu getreg () hinzuzufügen, da dies eher den Inhalt des Registers als eine mögliche Auswertung des Registers zurückgibt.
Jamessan

1

Um die Frage direkt zu beantworten, können Sie Folgendes in Ihre .vimrc-Datei einfügen, wenn Sie den Inhalt eines Registers schnell und einfach in ein anderes kopieren möchten. Sie können dann ausführen, <leader>rcabum den Inhalt des Registers ain das Register zu kopieren b. Als Beispiel habe ich mich <leader>rcfür "Registerkopie" entschieden.

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
Ich würde empfehlen getreg(sourceReg, 1).
Jamessan

Ah ja, stimmt. Fest.
Steve Vermeulen
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.