Vim Macro w każdej linii wizualnego wyboru

85

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

Last, First

W

First Last

i chciałbym, żeby działał na wszystkich tych liniach:

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

Jakieś pomysły guru Vima?

EDYCJA: To tylko przykład, oczywiście jest to trywialnie regexable, ale pojawiają się inne wystąpienia, które nie są tak łatwe, że wolałbym używać makr.

Stefan Mai
źródło
1
Szczerze mówiąc, prawdopodobnie wykonałbym to konkretne zadanie za pomocą wyrażenia regularnego. Ale pytanie jest nadal aktualne w bardziej złożonych przypadkach.
Jamie Wong
Dlaczego vim? Moim zdaniem sed jest bardziej odpowiedni.
kokosing
8
@kogut: Po co wychodzić z edytora, aby edytować tekst za pomocą jednowierszowego wyrażenia regularnego?
Stephen
1
Ok, o co chodzi;)
kokosing

Odpowiedzi:

152

Załóżmy, że masz makro, qktóre działało (i pozostało) w jednym wierszu. Następnie możesz uruchomić go w każdej wybranej linii za pomocą:

:'<,'>normal @q

(jeśli masz już wybraną grupę linii, naciskając :produkuje :'<,'>w wierszu poleceń)

Na przykład w poniższym makrze wszystkie słowa oprócz pierwszego w wierszu są pisane wielką literą:

:let @q="^dwgU$P"

Więc uruchamiam go na następującym (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.

Za pomocą powyższego normal @qpolecenia daje:

 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.
rampion
źródło
6
:let @q="^wgU$"
1
@rampion: czy w Twoim poleceniu jest literówka? dla mnie działa tylko tak::'<,'>normal! @q
oliver
3
@oliver: sprawdź swoje mapowania - być może dokonałeś przemapowania @q. From :help normal- "Jeśli podano [!], Mapowania nie będą używane."
rampion
2
@rampion: cholera ... masz rację! Używam szarpania i najwyraźniej jest z tym problem: ... Nie możesz wykonać makra z ": normal @a". Nadal nie jest to możliwe, ale możesz to wykonać za pomocą „: normal! @A” (z dokumentacji pomocy dla yankring)
oliver
1
Ja osobiście lubię map @w trybie wizualnym jak ten: vnoremap @ :normal @. W ten sposób nadal możesz robić @ato, czego się spodziewałeś (chociaż musisz później wcisnąć enter :()
LondonRob
19

Wybierz linie, a następnie naciśnij, :aby przejść do trybu poleceń. Vim automatycznie wypełni '<,'>, co ogranicza zakres do wybranych linii. Na przykład możesz użyć :spolecenia, aby wykonać zamianę:

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

Spowoduje to zamianę dwóch słów oddzielonych przecinkiem w każdym wierszu zaznaczenia wizualnego.

Możesz także użyć '<i '>jak każdej innej zakładki lub pozycji linii, np. Jako części polecenia ruchu, więc w trybie normalnym d'<usunie od aktualnej pozycji kursora do początku pierwszej linii w wizualnym zaznaczeniu. Znaki pozostają aktywne, nawet jeśli blok nie jest już wizualnie podświetlony.

Jeśli chcesz odtworzyć nagrane makro w każdym wierszu, musisz wykonać makro za pomocą :normalpolecenia. Niestety :normalpolecenie nie działa na szeregu linii, ale możesz to naprawić za pomocą :globalpolecenia. To uruchamia :expolecenie w każdym wierszu, który pasuje do wyrażenia regularnego, więc możesz to zrobić:

:'<,'>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
Dave Kirby
źródło
Jest to lepsze niż zaakceptowana odpowiedź, ponieważ obsługuje makra, które dodają nowe wiersze.
Jan Warchoł
@Dave, Kirby Może lepiej byłoby wymienić się ^z nim, .aby makro działało tylko w wierszach zawierających jakiś tekst, prawda?
SergioAraujo
1

Możesz dodać poniższą funkcję do swojej ~/.vimrclub po prostu skopiować ją do przeglądarki 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żesz zastosować dowolne makro na selekcji wizualnej. Musisz podać literę makra jako argument, na przykład:

:Rover a
SergioAraujo
źródło