Vim Macro на кожному рядку візуального виділення


85

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

Last, First

В

First Last

і я хотів би, щоб він працював по всіх цих рядках:

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

Будь-які ідеї гуру Vim?

РЕДАГУВАТИ: Це лише приклад, очевидно, це тривіальне регулярне використання, але трапляються й інші випадки, які не настільки прості, що я волів би використовувати макроси.


1
Чесно кажучи, я б, мабуть, виконував саме це завдання за допомогою регулярного виразу. Але питання все ще справедливе для більш складних справ.
Джеймі Вонг,

Чому вим? На мій погляд, sed є більш доречним.
kokosing

8
@kogut: Навіщо виходити з редактора, щоб редагувати текст за допомогою одного рядкового регулярного виразу?
Стівен

1
Гаразд, Ви зрозуміли думку;)
kokosing

Відповіді:


152

Припустимо, у вас був макрос, 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.

6
:let @q="^wgU$"

1
@rampion: чи є у вашій команді друкарська помилка? для мене це працює лише так::'<,'>normal! @q
Олівер

3
@oliver: перевірте свої зіставлення - можливо, ви перепризначили @q. From :help normal- "Якщо вказано [!], Відображення не будуть використовуватися."
чемпіон

2
@rampion: блін ... ти маєш рацію! Я використовую yankring і, мабуть, з цим виникає проблема: ... Ви не можете виконати макрос за допомогою ": normal @a". Це по - раніше не представляється можливим, але ви можете виконати його з «: нормальний @a» (від допомоги Документів yankring)
олівер

1
Я особисто хотів би відобразити @в візуальному режимі , як це: vnoremap @ :normal @. Таким чином, ви все ще можете робити @aте, що очікували (хоча вам потім потрібно натиснути Enter :()
LondonRob

19

Виберіть рядки, а потім натисніть, :щоб увійти в командний режим. 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

Це краще, ніж прийнята відповідь, оскільки вона підтримує макроси, які додають нові рядки.
Ян Вархол,

@ Dave, Кірбі Може бути краще було б обмін ^з , .щоб зробити запуск макросу тільки на лініях , що має якийсь - то текст, не буде?
SergioAraujo

1

Ви можете додати функцію нижче до свого ~/.vimrcабо просто скопіювати її у своєму браузері та запуску:@+

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

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

:Rover a
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.