2010-07-26 11 views
67

Mi piacerebbe eseguire una macro su ogni riga di una selezione, piuttosto che sommare il numero di linee nella mia testa. Per esempio, potrei scrivere una macro per trasformare:Vim Macro su ogni riga di selezione visiva

Last, First 

Into

First Last 

e mi piacerebbe farlo funzionare su tutte queste linee:

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

Tutte le idee guru Vim ?

EDIT: Questo è solo un esempio, ovviamente questo è trivialy regexable, ma ci sono altri esempi che non sono così facili che preferirei usare le macro.

+1

Per essere onesti, probabilmente faccio questo particolare compito con espressioni regolari. Ma la domanda è ancora valida per i casi più complessi. –

+0

Perché vim? Secondo me sed è più appropriato. – kokosing

+7

@kogut: Perché uscire dall'editor per modificare il testo con una regex a una riga? – Stephen

risposta

124

Supponete di avere una macro q che correva (ed è rimasto) su un singolo linea.Allora si potrebbe eseguirlo su ogni riga la selezione con:

:'<,'>normal @q 

(se si dispone già di un gruppo di linee selezionate, colpendo : produce :'<,'> sulla riga di comando)

Ad esempio, la seguente macro capitalizza ogni parola, ma la prima su una linea:

:let @q="^dwgU$P" 

Così in esecuzione sul seguente (in cui vengono selezionati i + linee)

0.123.516,41 mila
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. 

Con il comando precedente normal @q, produce:

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. 
+6

': let @q ="^wgU $ "' –

+0

@ Poger Pate: beh, sì, se vuoi giocare a golf :) – rampion

+0

@rampion: c'è un errore nel tuo comando? per me funziona solo così: ': '<,'> normale! @ q' – oliver

12

Selezionare le linee quindi premere : per accedere alla modalità comandi. Vim riempirà automaticamente '<,'>, che limita l'intervallo alle linee selezionate. Per il vostro esempio è possibile utilizzare il comando :s di fare lo swap:

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

Ciò scambiare due parole separate da una virgola su ogni riga nella selezione visiva.

È inoltre possibile utilizzare '< e '> come qualsiasi altro segnalibro o posizione di linea, ad es. come parte di un comando di movimento, quindi in modalità normale, d'< eliminerà dalla posizione corrente del cursore all'inizio della prima riga nella selezione visiva. I segni rimangono in vigore anche se il blocco non è più visivamente evidenziato.

Se si desidera riprodurre una macro registrata su ogni riga, è necessario eseguire la macro con il comando :normal. Sfortunatamente il comando :normal non funziona su un intervallo di linee, ma è possibile risolverlo con il comando :global. Questo viene eseguito un comando :ex su ogni riga che corrisponde a un'espressione regolare, in modo da poter fare questo:

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

Spiegazione:

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

': help: intervallo normale' –

+0

Questo è migliore della risposta accettata perché supporta macro che aggiungono nuove linee. –

+0

[@Dave, Kirby] (https://stackoverflow.com/users/206417/dave-kirby) Forse sarebbe meglio scambiare '^' con '.' per far funzionare la macro solo su righe che contengono del testo, non lo sarebbe? – SergioAraujo

0

È possibile aggiungere la funzione qui sotto al tuo ~/.vimrc o semplicemente copiarlo sul vostro browser e l'esecuzione :@+

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

Il vantaggio è che puoi applicare qualsiasi macro alla selezione visiva. È necessario dare la lettera macro come argomento, come:

:Rover a 
Problemi correlati