2010-07-26 17 views
67

Je voudrais exécuter une macro sur chaque ligne d'une sélection, plutôt que de totaliser le nombre de lignes dans ma tête. Par exemple, je pourrais écrire une macro pour transformer:Macro Vim sur chaque ligne de sélection visuelle

Last, First 

Dans

First Last 

et je voudrais à courir sur toutes ces lignes:

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

Toutes les idées gourous Vim ?

EDIT: Ceci est juste un exemple, évidemment c'est trivialy regexable, mais il y a d'autres instances qui ne sont pas si faciles que je préfère utiliser des macros.

+1

Pour être honnête, je ferais probablement cette tâche particulière avec regex. Mais la question est toujours valable pour les cas plus complexes. –

+0

Pourquoi vim? À mon avis, sed est plus approprié. – kokosing

+7

@kogut: Pourquoi quitter votre éditeur pour éditer votre texte avec une regex à une ligne? – Stephen

Répondre

124

Supposons que vous ayez une q macro qui a couru (et est resté) sur un seul ligne.Ensuite, vous pouvez l'exécuter sur chaque ligne dans votre sélection avec:

:'<,'>normal @q 

(si vous avez déjà un groupe de lignes sélectionnées, frapper : produit :'<,'> sur la ligne de commande)

Par exemple, la macro suivante capitalise tous les mots, mais la première sur une ligne:

:let @q="^dwgU$P" 

donc en cours d'exécution sur les éléments suivants (où les + lignes sont sélectionnées)

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. 

Avec la commande normal @q ci-dessus, produit:

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

@Roger Pate: eh bien, oui si vous voulez jouer au golf :) – rampion

+0

@rampion: y at-il une faute de frappe dans votre commande? pour moi cela fonctionne seulement comme ceci: ': '<,'> normal! @ q' – oliver

12

Sélectionnez les lignes, puis appuyez sur : pour passer en mode commande. Vim remplira automatiquement '<,'>, ce qui limite la portée aux lignes sélectionnées. Pour votre exemple, vous pouvez utiliser la commande :s pour faire l'échange:

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

Cela échanger deux mots séparés par une virgule sur chaque ligne dans la sélection visuelle.

Vous pouvez également utiliser '< et '> comme tout autre signet ou position de ligne, par ex. en tant que partie d'une commande de mouvement, donc en mode normal d'< va supprimer de la position actuelle du curseur au début de la première ligne dans la sélection visuelle. Les marques restent actives même si le bloc n'est plus surligné visuellement.

Si vous souhaitez relire une macro enregistrée sur chaque ligne, vous devez exécuter la macro avec la commande :normal. Malheureusement, la commande :normal ne fonctionne pas sur une plage de lignes, mais vous pouvez la corriger avec la commande :global. Cela exécute une commande :ex sur chaque ligne qui correspond à une expression régulière, vous pouvez le faire:

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

Explication:

:'<,'>  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: normal-range' –

+0

C'est mieux que la réponse acceptée, car il supporte les macros qui ajoutent de nouvelles lignes. –

+0

[@Dave, Kirby] (https://stackoverflow.com/users/206417/dave-kirby) Peut-être serait-il préférable d'échanger '^' avec '.' pour que la macro ne s'exécute que sur les lignes contenant du texte, ne le ferait pas? – SergioAraujo

0

Vous pouvez ajouter la fonction ci-dessous à votre ~/.vimrc ou simplement copier sur votre navigateur et en cours d'exécution :@+

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

L'avantage est que vous pouvez appliquer n'importe quelle macro sur la sélection visuelle. Vous devez donner la lettre macro comme argument, comme:

:Rover a