Makro Vim na każdej linii wizualnego zaznaczenia

Chciałbym uruchomić makro na każdej linii w zaznaczeniu, zamiast sumować liczbę linii w mojej głowie. Na przykład, mogę napisać makro do przekształcenia:

Last, First

Do

First Last

I chciałbym, aby działał na wszystkich tych liniach:

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

Jakieś pomysły Vim Guru?

EDIT: to tylko przykład, oczywiście jest to trywialnie powtarzalne, ale są inne przypadki, które pojawiają się, które nie są takie proste, że wolałbym używać makr.

Author: Stefan Mai, 2010-07-26

3 answers

Załóżmy, że masz makro q, które działało (i pozostało) na jednej linii. Następnie można go uruchomić na każdej linii w zaznaczeniu za pomocą:

:'<,'>normal @q

(Jeśli masz już zaznaczoną grupę linii, naciśnięcie : spowoduje wyświetlenie :'<,'> w wierszu poleceń)

Na przykład, następujące makro jest pisane wielkimi literami każdego słowa, Ale pierwszego w wierszu:

:let @q="^dwgU$P"

Więc uruchamianie go na następujących (gdzie zaznaczone są linie +)

 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.

Z powyższym poleceniem normal @q , produkuje:

 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.
 133
Author: rampion,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-26 19:55:34

Wybierz linie, a następnie naciśnij :, aby przejść do trybu poleceń. Vim automatycznie wypełni '<,'>, co ograniczy zakres do wybranych linii. Dla przykładu możesz użyć polecenia :s do wykonania zamiany:

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

Spowoduje zamianę dwóch słów oddzielonych przecinkiem w każdej linii w zaznaczeniu wizualnym.

Możesz również użyć '< i '> jak każda inna pozycja zakładki lub linii, np. jako część polecenia ruch, więc w trybie normalnym d'< usunie z bieżącego pozycja kursora do początku pierwszej linii w zaznaczeniu wizualnym. Znaki pozostają w mocy, nawet jeśli blok nie jest już wizualnie podświetlony.

Jeśli chcesz odtworzyć zarejestrowane makro w każdej linii, musisz wykonać makro za pomocą polecenia :normal. Niestety polecenie :normal nie działa na wielu liniach, ale można to naprawić za pomocą polecenia :global. To uruchamia polecenie :ex w każdym wierszu, który pasuje do wyrażenia regularnego, więc możesz to zrobić to:

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

Wyjaśnienie:

:'<,'>       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
 13
Author: Dave Kirby,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-26 19:58:35

Możesz dodać poniższą funkcję do swojego ~/.vimrc lub po prostu skopiować ją w przeglądarce i uruchomić :@+

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

Zaletą jest to, że można zastosować dowolne makro na zaznaczeniu wizualnym. Jako argument musisz podać literę makra, np.:

:Rover a
 0
Author: SergioAraujo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-23 17:56:58