Привет, коллеги. Какие есть способы повторить последовательность действий? Особенно интересно уметь повторять сложные наборы команд.
Команды повтора
1. Есть команда . ("точка"), которая повторяет последнюю команду нормального режима, кроме движения. Скажем, вы удалили два слова: dw. Можете повторить, нажав в нужном месте точку и сэкономив два нажатия. Более того! Команда c, удаляющая текст и включающая режим вставки, считается вплоть до выхода из режима вставки! То есть, допустим, у вас написано
long_var_name = long_var_name + 42
и вы поставили курсор на первую l и нажали cw. Первое имя исчезло и можно ввести другое. Вы ввели short_var_name и нажали <ESC>. Поставили курсор на l после знака равенства и нажали точку. Всё.
2. Есть команды n и N, повторяющие последний поиск в том же направлении и в противоположном. Есть &, повторяющая последнюю замену. Вариант g& повторяет замену глобально. И есть @:, повтор последней команды режима командной строки.
Очень эффективно повторять связку "найти и сделать что-то" (n.) или "найти и заменить, если надо" (n&). Это для действий сложнее одноклавишных команд, которые надо повторять, но не регулярно. Причем повторять больше, чем несколько раз, но не сотни раз.
Еще можно сделать привязку и повторять действие одной клавишей. Если надо несколько команд соединить в одну, то для этого применяется "конвейер" |. Это просто соединитель команд, так что они выполняются одна за другой. Например,
:map <F4> :w! | :mksession! | echo "Session updated"
Привязки хороши для команд, которые нужны регулярно, но которые не надо повторять сотни раз.
Как сделать оператор, то есть команду, которую применяют к движению или выделению, я расскажу в одной из ближайших заметок.
3. Последовательность действий можно записать в макрос, помеченный латинской буквой. qa начнет запись в регистр a, q закончит запись. Потом можно проиграть последовательность @a или повторить @@. Можно указать повторитель: 500@a.
Макросы удобны для сложных повторов в стиле "запомни и повтори". Возможность выполнить макрос сразу много раз позволяет повторить действие многократно. Это важно, если повторов надо десятки, сотни, тысячи.
4. Есть фильтры строк :g и :v, позволяющие выполнить команду на строках, подпадающих под шаблон (или на не подпадающих). Команды режима командной строки, но можно применять и команды нормального режима через normal. Можно даже сами фильтры строк применять в фильтрах строк, только вложенный применяется только к данной строке. Так можно найти строки, подпадающие под одно выражение и не подпадающие под другое, и обработать их.
Есть операция замены :s///, которая может быть выполнена на всем файле (:%s), на диапазоне строк и как команда на фильтре строк.
Хакерский прием: иногда можно использовать диапазон строк, чтобы повторить команду. Команда выполняется формально на строке, но может не иметь отношения к строке как таковой.
Можно выполнить сохраненные в регистре (например, a) команды как команды командной строки, введя в ней :@a. И потом повторить, введя :@ или :@@. Это удобно, если у вас нет прав на запись, например, и вы не можете сохранить команды в файл как скрипт.
5. Если права на запись есть, можно сделать скрипт, записав команды в файл. Мы сейчас не рассматриваем программирование (циклы, условия, переменные, функции - это в других заметках). Пока просто набор команд для повтора. Например, для раскраски синтаксиса или еще для чего-нибудь полезного.
Выполнить скрипт позволяет команда :source, сокращенно :so. Она читает из файла команды построчно и выполняет их в командной строке. Не обязательно ставить двоеточие. Нормальный режим доступен через normal. Однако, скажем, если вы вызвали команду bash (через !), то Вим попросит нажать ввод, что не всегда уместно.
Если использовать :source!, то команды толкуются как команды нормального режима. Командная строка доступна через двоеточие. Однако теперь файл читается посимвольно, так что конец строки воспринимается как нажатие клавиши ввода.
Команда source может использоваться в скриптах, то есть допустима вложенность. Символ <sname> будет заменен на имя исполняемого файла. С учетом преобразований имен файлов можно делать интересные вещи. Например,
:source <sfile>:h/other.vimrc
Преобразователь :h отцепляет имя файла, оставляя путь, так что файл other.vimrc будет взят из того же каталога, в котором выполняется данный.
Длинные строки можно разрывать, помещая обратный слеш (\) в начале строки-продолжения. Это немного необычно:
autocommand BufReadPost *
\set nowrap
Перед слешем могут быть пробелы, которые игнорируются. А вот в конце продолжаемой строки пробелы считаются как часть команды (в ряде случаев они не важны, но порой бывают важны). Если пробел нужен, лучше поставить его после слеша на строке продолжения.
Удачи, коллеги!