Pull to refresh

Макросы в Vim — это просто

VIM *
Tutorial

Макросы в Vim


Очень странно, с одной стророны тема довольно банальная, а с другой ни тут, ни на просторах интернета не видно хорошего понимания такой важной темы, которая может иногда сильно упростить задачу редактирования текста. К написанию меня подтолкнуло обсуждение макросов в Emacs в блоге Avdi Grimm'а, где в своё время никто не смог внятно объяснить, что в Vim есть то, чего ожидает автор поста от достойного текстового редактора. Исправим это, в первую очередь в себе, а потом пойдём и скажем этим из интернета, что они не правы.

Какие задачи редактирования текста помогут решить макросы? Например, такую: вот в этой самой строке, которую вы читаете, взять и все запятые поменять на 0. Можно вспомнить регулярные выражения, но не все их любят, и уж тем более не все помнят, как вставлять с их помощью перенос строки, а если вам нужно заменять какие-то символы, которые используются в регулярных выражениях как служебные, вы уже отвлеклись от своей основной задачи и вместо редактирования текста занимаетесь написанием регулярного выражения для поиска и замены, пробуя и ошибаясь.
Макросы позволят это сделать быстрее, с меньшим отвлечением на вспоминание и написание чего-либо. Запомнить как работают макросы очень легко, и это войдёт в ваш ежедневный аресенал наряду с прыжками по тексту.

В этом топике мы научимся использовать макросы с этой самой задачей.

Давайте сначала вспомним, как это сделать вручную.
f,r0
После чего можно нажимать последовательно ; для повторного поиска и . для повторения предыдущего действия. Но в какой-то момент это может стать не так просто, например, вам нужно добавить пару каких-то знаков между делом. Точка уже не сработает и нужно будет опять нажимать r0. Или этих запятых окажется довольно много, и щёлкать поочерёдно ; и . придётся довольно много раз. В этот момент что-то вам уже подсказывает, что такой механический труд можно автоматизировать.

Основы
Многократные повторения и рекурсивный вызов
Редактирование макросов
Вечные макросы
Всякое

Основы


Для записи и хранения макросов в Vim используются регистры. Те самые, в которые можно копировать текст и те самые, на которые можно ставить пометки. Регистры обозначаются латинскими буквами без учёта регистра (a и A — один и тот же регистр), цифрами, и даже специальными символами, то есть хватит их на всех.

Важно. В регистрах хранится не что-то магическое, в регистрах хранится простой текст.

Для записи макроса в регистр a вопспользуемся следующей командой:
qaf,r0q
Первый кю q запускает запись макроса, и так до нажатия q для подтверждения записи.
Теперь, чтобы запустить макрос повторно, нам нужно нажать @a, и запустится на выполнение макрос, хранящийся в регистре a. Мы можем традиционно для Vim написать 100@a, и макрос будет выполнен 100 раз, заменив 100 или меньше (если в строке их меньше) запятых на 0.

Многократные повторения и рекурсивный вызов


Иногда сколько у нас запятых в строке мы не знаем, поэтому после запуска 100@a нам приходится вручную проверять, не осталось ли ещё.
Можно довольно просто сделать так, чтобы макрос вызывал сам себя. Запишем тот же самый макрос, который нужно будет вызывать всего один раз, а дальше он будет сам вызывать себя:
qaf,r0@aq
В данном случае, его запись ещё не произозшла, но запуск уже указан. Важно, чтобы в этом регистре ничего на момент записи не хранилось. Для этого есть два способа. Первый — это чистить содержимое регистра перед записью ещё тремя нажамиями, qaq, то есть записью пустой последовательности. Второй — это делать вызов последнего вызыванного макроса с помощью @@.

Важно. Выполнение цепочки или серии исполнения макросов приостанавливается в тот самый момент, когда одна из команд fFtT, то есть поиска символа в строке, не удаётся. То есть, например, у нас не осталось больше в строке запятых. Естественно, даже если вы указали, что макрос нужно выполнить 100 раз, а запятых было всего две, макрос выполнится два раза, а на третий остановится на поиске и больше продолжать не будет. Точно так же с рекурсивным макросом.

Удобно то, что при записи макроса происходит его первое исполнение, то есть мы сразу видим, правильно ли его записали.

Редактирование макросов


Если что-то пошло не так, и хочется увидеть, что же мы записали, можно воспользоваться стандартной функцией Vim, и вставить содержимое регистра a прямо в текст: "ap.
Прямо в редакторе вы увидите текст, который является последовательностью команд:
af,r0@a

Допустим, вы решили, что менять текст нужно не на 0, а на 1, и вы редактируете текст макроса:
af,r1@a

и копируете его в регистр a с помощью 0"ay$.

Вечные макросы


Стоит заметить, что регистры постоянны, если вы выйдете из Vim, а потом зайдёте снова, содержимое регистра останется неприкосновенным. Хранится оно по умолчанию в файле ~/.viminfo.

Важно. Содержимое регистра легко случайно перезаписать, и если вы хотите, чтобы какие-то макросы существовали в каких-то регистрах постоянно, имеет смысл добавить их в .vimrc, или лучше в отдельный файл с макросами, включаемый в .vimrc:
  let @a='af,r1@a'


Всякое


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

Чтобы избежать случайных переходов по нажатию Q в Ex режим, имеет смысл назначить Q на вызов предыдущего макроса:
    nnoremap Q @@


Полезная информация:
:help registers
:help :registers
:help :recording

Для дальнейшего изучения:
Продвинутые макросы Vim (англ.)
Tags:
Hubs:
Total votes 31: ↑30 and ↓1 +29
Views 22K
Comments Comments 8