Vim Macro на каждой строке визуального выбора - PullRequest
77 голосов
/ 26 июля 2010

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

Last, First

Into

First Last

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

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

Есть идеи, Vim gurus?

РЕДАКТИРОВАТЬ: Это всего лишь пример, очевидно, это тривиально regexable, но есть другие примеры, которые не так просто, что я предпочел бы использовать макросы.

Ответы [ 3 ]

141 голосов
/ 26 июля 2010

Предположим, у вас есть макрос 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.
16 голосов
/ 26 июля 2010

Выберите строки, затем нажмите :, чтобы войти в командный режим. 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
1 голос
/ 23 сентября 2017

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

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

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

:Rover a
...