Vim Macro на каждой линии визуального выделения

Я хотел бы запустить макрос в каждой строке в выделенном виде, а не суммировать количество строк в моей голове. Например, я могу написать макрос для преобразования:

Last, First

В

First Last

и я бы хотел, чтобы он работал на всех этих строках:

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

Любые идеи Vim гуру?

EDIT: Это просто пример, очевидно, что это тривиально повторяемо, но есть и другие экземпляры, которые не так-то просто, что я предпочитаю использовать макросы.

Ответ 1

Предположим, что у вас есть макрос q, который запускался (и оставался) в одной строке. Затем вы можете запустить его в каждой строке в своем выборе с помощью:

:'<,'>normal @q

(если у вас уже есть группа выделенных строк, нажатие : вызывает :'<,'> в командной строке)

Например, следующий макрос заглаживает каждое слово, кроме первого в строке:

:let @q="^dwgU$P"

Итак, запустите его на следующем (где выбраны строки +)

 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.

С помощью указанной выше команды normal @q выдает:

 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.

Ответ 2

Выберите строки, затем нажмите :, чтобы войти в командный режим. Vim автоматически заполнит '<,'>, который ограничивает диапазон выбранными линиями. Для вашего примера вы можете использовать команду :s для обмена:

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

Это приведет к замене двух слов, разделенных запятой на каждую строку в визуальном выборе.

Вы также можете использовать '< и '>, как и любую другую закладку или позицию линии, например. как часть команды перемещения, поэтому в нормальном режиме d'< будет удаляться из текущей позиции курсора в начало первой строки в визуальном выборе. Знаки остаются в силе, даже если блок больше не визуально подсвечен.

Если вы хотите воспроизвести записанный макрос в каждой строке, вам нужно выполнить макрос с помощью команды :normal. К сожалению, команда :normal не работает с рядом строк, но вы можете исправить это с помощью команды :global. Это запускает команду :ex в каждой строке, которая соответствует регулярному выражению, поэтому вы можете сделать это:

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

Пояснение:

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

Ответ 3

Вы можете добавить функцию ниже к ~/.vimrc или просто скопировать ее в свой браузер и запустить :@+

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

Преимущество заключается в том, что вы можете применить любой макрос к визуальному выбору. Вам нужно указать макрокоманду как аргумент, например:

:Rover a