web-dev-qa-db-fra.com

Macro Vim sur chaque ligne de sélection visuelle

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:

Last, First

Dans

First Last

et je voudrais qu'il fonctionne sur toutes ces lignes:

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

Des idées gourous Vim?

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

79
Stefan Mai

Supposons que vous disposiez d'une macro q qui s'exécutait (et restait) sur une seule ligne. Ensuite, vous pouvez l'exécuter sur chaque ligne de votre sélection avec:

:'<,'>normal @q

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

Par exemple, la macro suivante met en majuscule chaque mot, mais le premier sur une ligne:

:let @q="^dwgU$P"

Donc, l'exécuter sur ce qui suit (où le + 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 ce qui précède normal @q commande, 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.
141
rampion

Sélectionnez les lignes puis appuyez sur : Pour passer en mode commande. Vim remplira automatiquement '<,'>, Ce qui restreint la plage aux lignes sélectionnées. Pour votre exemple, vous pouvez utiliser la commande :s Pour effectuer le swap:

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

Cela permutera deux mots séparés par une virgule sur chaque ligne de la sélection visuelle.

Vous pouvez également utiliser '< Et '> Comme tout autre signet ou position de ligne, par exemple dans le cadre d'une commande de mouvement, donc en mode normal d'< supprimera de la position actuelle du curseur jusqu'au début de la première ligne de la sélection visuelle. Les marques restent en vigueur même si le bloc n'est plus mis en évidence visuellement.

Si vous souhaitez rejouer 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 résoudre ce problème avec la commande :global. Cela exécute une commande :ex Sur chaque ligne qui correspond à une expression régulière, vous pouvez donc faire ceci:

:'<,'>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
16
Dave Kirby

Vous pouvez ajouter la fonction ci-dessous à votre ~/.vimrc ou copiez-le simplement sur votre navigateur et exécutez :@+

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 macro lettre comme argument, comme:

:Rover a
1
SergioAraujo