Vim Macro op elke lijn van visuele selectie

Ik wil graag een macro uitvoeren op elke regel in een selectie, in plaats van het aantal regels in mijn hoofd op te tellen. Ik zou bijvoorbeeld een macro kunnen schrijven om te transformeren:

Last, First

Into

First Last

en ik zou graag willen dat het op al deze regels wordt uitgevoerd:

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

Enige ideeën Vim-goeroes?

EDIT: dit is slechts een voorbeeld, dit is natuurlijk triviaal regexable, maar er zijn andere gevallen die niet zo eenvoudig zijn dat ik liever macro’s zou gebruiken.


Antwoord 1, autoriteit 100%

Stel dat je een macro qhad die liep (en bleef) op een enkele regel. Dan zou je het op elke regel in je selectie kunnen uitvoeren met:

:'<,'>normal @q

(als je al een groep regels hebt geselecteerd, geeft het indrukken van ::'<,'>op de opdrachtregel)

Bijvoorbeeld, in de volgende macro wordt elk woord met een hoofdletter geschreven, behalve het eerste op een regel:

:let @q="^dwgU$P"

Dus als volgt uitvoeren (waar de +regels zijn geselecteerd)

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.

Met het bovenstaande normal @qcommando, produceert:

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.

Antwoord 2, autoriteit 11%

Selecteer de regels en druk vervolgens op :om de opdrachtmodus te openen. Vim vult automatisch '<,'>in, wat het bereik beperkt tot de geselecteerde regels. Voor jouw voorbeeld kun je het :scommando gebruiken om de swap uit te voeren:

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

Hiermee worden op elke regel in de visuele selectie twee woorden, gescheiden door een komma, verwisseld.

U kunt '<en '>ook gebruiken zoals elke andere bladwijzer of lijnpositie, b.v. als onderdeel van een bewegingscommando, dus in de normale modus zal d'<verwijderen van de huidige cursorpositie naar het begin van de eerste regel in de visuele selectie. De markeringen blijven van kracht, zelfs als het blok niet langer visueel wordt gemarkeerd.

Als je een opgenomen macro op elke regel wilt afspelen, moet je de macro uitvoeren met het :normalcommando. Helaas werkt het :normalcommando niet op een reeks regels, maar je kunt dat oplossen met het :globalcommando. Dit voert een :ex-opdracht uit op elke regel die overeenkomt met een regex, dus u kunt dit doen:

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

Uitleg:

:'<,'>       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

Antwoord 3

U kunt de onderstaande functie toevoegen aan uw ~/.vimrcof deze eenvoudig in uw browser kopiëren en :@+

uitvoeren

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

Het voordeel is dat u elke macro op de visuele selectie kunt toepassen.
Je moet de macroletter als argument geven, zoals:

:Rover a

Other episodes