Vim-Makro in jeder Zeile der visuellen Auswahl

86

Ich möchte in jeder Zeile einer Auswahl ein Makro ausführen, anstatt die Anzahl der Zeilen in meinem Kopf zu summieren. Zum Beispiel könnte ich ein Makro schreiben, um es zu transformieren:

Last, First

In

First Last

und ich möchte, dass es auf all diesen Zeilen läuft:

Stewart, John 
Pumpkin, Freddy
Mai, Stefan
...

Irgendwelche Ideen Vim Gurus?

EDIT: Dies ist nur ein Beispiel, offensichtlich ist dies trivial regexable, aber es gibt andere Instanzen, die nicht ganz so einfach sind, dass ich lieber Makros verwenden würde.

Stefan Mai
quelle
1
Um ehrlich zu sein, würde ich diese spezielle Aufgabe wahrscheinlich mit Regex erledigen. Die Frage gilt jedoch weiterhin für komplexere Fälle.
Jamie Wong
Warum vim? Meiner Meinung nach ist sed angemessener.
Kokosing
8
@kogut: Warum beenden Sie Ihren Editor, um Ihren Text mit einem einzeiligen regulären Ausdruck zu bearbeiten?
Stephen
1
Ok, du hast es verstanden;)
Kokosing

Antworten:

153

Angenommen, Sie hatten ein Makro q, das in einer einzelnen Zeile ausgeführt wurde (und blieb). Dann können Sie es in jeder Zeile Ihrer Auswahl ausführen mit:

:'<,'>normal @q

(Wenn Sie bereits eine Gruppe von Zeilen ausgewählt haben, wird durch Drücken von in der Befehlszeile :erzeugt. :'<,'>)

Das folgende Makro schreibt beispielsweise jedes Wort außer dem ersten in einer Zeile groß:

:let @q="^dwgU$P"

Führen Sie es also wie folgt aus (wo die +Zeilen ausgewählt sind)

 0000: a long long time ago
 0001: in a galaxy far away
+0002: naboo was under an attack
+0003: and i thought me and qui-gon jinn
+0004: could talk the federation in
 0005: to maybe cutting them a little slack.

Mit dem obigen normal @qBefehl wird Folgendes erzeugt:

 0000: a long long time ago
 0001: in a galaxy far away
 0002: naboo WAS UNDER AN ATTACK
 0003: and I THOUGHT ME AND QUI-GON JINN
 0004: could TALK THE FEDERATION IN
 0005: to maybe cutting them a little slack.
Rampion
quelle
6
:let @q="^wgU$"
1
@rampion: Gibt es einen Tippfehler in Ihrem Befehl? für mich funktioniert es nur so::'<,'>normal! @q
oliver
3
@oliver: Überprüfen Sie Ihre Zuordnungen - möglicherweise haben Sie sie neu zugeordnet @q. Von :help normal- "Wenn das [!] Angegeben ist, werden keine Zuordnungen verwendet."
Rampion
2
@rampion: verdammt ... du hast recht! Ich benutze Yankring und anscheinend gibt es ein Problem damit: ... Sie können kein Makro mit ": normal @a" ausführen. Es ist immer noch nicht möglich, aber Sie können es mit ": normal! @A" (aus den Hilfedokumenten von yankring)
ausführen
1
Ich persönlich mag es, @im visuellen Modus wie folgt abzubilden : vnoremap @ :normal @. Auf diese Weise können Sie immer noch das tun, was @aSie erwarten (obwohl Sie danach die Eingabetaste drücken müssen :()
LondonRob vor
19

Wählen Sie die Zeilen aus und drücken Sie :, um den Befehlsmodus aufzurufen. Vim wird automatisch ausgefüllt '<,'>, wodurch der Bereich auf die ausgewählten Zeilen beschränkt wird. In Ihrem Beispiel können Sie den :sBefehl verwenden, um den Austausch durchzuführen:

:'<,'>s/\(\w\+\), \(\w\+\)/\2, \1/

Dadurch werden zwei durch ein Komma getrennte Wörter in jeder Zeile der visuellen Auswahl ausgetauscht.

Sie können auch jedes andere Lesezeichen oder jede andere Zeilenposition verwenden '<und '>mögen, z. B. als Teil eines Bewegungsbefehls, sodass im normalen Modus d'<von der aktuellen Cursorposition bis zum Anfang der ersten Zeile in der visuellen Auswahl gelöscht wird. Die Markierungen bleiben auch dann wirksam, wenn der Block nicht mehr optisch hervorgehoben wird.

Wenn Sie ein aufgezeichnetes Makro in jeder Zeile wiedergeben möchten, müssen Sie das Makro mit dem :normalBefehl ausführen . Leider :normalfunktioniert der Befehl nicht in einer Reihe von Zeilen, aber Sie können dies mit dem :globalBefehl beheben . Dadurch wird in :exjeder Zeile ein Befehl ausgeführt, der einem regulären Ausdruck entspricht. Sie können dies also tun:

:'<,'>g/^/ norm @a

Erläuterung:

:'<,'>       for every line in the visual block
g/^/         on every line that matches the regex /^/ - i.e. every line
norm         run in normal mode
@a           the macro recorded in a
Dave Kirby
quelle
Dies ist besser als die akzeptierte Antwort, da Makros unterstützt werden, die neue Zeilen hinzufügen.
Jan Warchoł
@ Dave, Kirby Vielleicht besser Austausch wäre ^mit .dem Makro läuft auf Linien nur zu machen , die einen Text hat, würde das nicht?
SergioAraujo
1

Sie können die folgende Funktion zu Ihrer hinzufügen ~/.vimrcoder sie einfach in Ihren Browser kopieren und ausführen:@+

fun! RunMacroOverSelection(macroname)
    execute "'<,'>normal @". a:macroname
endfun
com -nargs=1 Rover :call RunMacroOverSelection(<f-args>)
nnoremap <leader>r :Rover<space>

Der Vorteil ist, dass Sie ein beliebiges Makro auf die visuelle Auswahl anwenden können. Sie müssen den Makrobuchstaben als Argument angeben, z.

:Rover a
SergioAraujo
quelle