Найти в Дзене
Блокнот математика

Рубрика "Секреты Вим". Подробнее о привязках, часть 1: рекурсия и повторители

Привет, коллеги. Материал о привязках, или горячих клавишах, у нас уже был. Вим позволяет назначить клавише (например, Q или F2, которую надо записать как <F2>), сочетанию клавиш (<S-F2> или <C-Q>) или последовательности (qw или ,, или даже qwertyu) команду, которую надо выполнить, или текст, который будет введен. Особняком стоят сокращения, позволяющие просто вместо одного текста ввести другой, скажем, "тэи" раскрыть в "тензор энергии-импульса" или "hte" в "the". Нотацию уголковых скобок мы обсудили недавно во всех деталях. Там всё довольно интуитивно. На базовом уровне достаточно знать команды :map, для нормального режима и режима командной строки, и imap для режима вставки. Примеры: map <F2> :w<CR>
imap <F2><esc>:w<CR>a Обе привязки делают клавишу Ф2 горячей: она сохраняет файл. В режиме вставки тоже, но обратите внимание: "правая часть", то есть определяемая команда, выполняется в том режиме, в котором определена. То есть из режима вставки сначала надо выйти через <ESC>, а потом у

Привет, коллеги. Материал о привязках, или горячих клавишах, у нас уже был. Вим позволяет назначить клавише (например, Q или F2, которую надо записать как <F2>), сочетанию клавиш (<S-F2> или <C-Q>) или последовательности (qw или ,, или даже qwertyu) команду, которую надо выполнить, или текст, который будет введен. Особняком стоят сокращения, позволяющие просто вместо одного текста ввести другой, скажем, "тэи" раскрыть в "тензор энергии-импульса" или "hte" в "the".

Нотацию уголковых скобок мы обсудили недавно во всех деталях. Там всё довольно интуитивно.

https://sun9-43.userapi.com/c858328/v858328441/149da0/7V98SA-Zxq0.jpg
https://sun9-43.userapi.com/c858328/v858328441/149da0/7V98SA-Zxq0.jpg

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

map <F2> :w<CR>
imap <F2><esc>:w<CR>a

Обе привязки делают клавишу Ф2 горячей: она сохраняет файл. В режиме вставки тоже, но обратите внимание: "правая часть", то есть определяемая команда, выполняется в том режиме, в котором определена. То есть из режима вставки сначала надо выйти через <ESC>, а потом уже сохранять файл. Потом можно опять войти в режим вставки через а.

Если вам надо ввести то, что переопределено (речь про режим вставки), то это можно сделать, набирая текст медленно. Скажем, если у вас

imap hte the

(хотя лучше это делать сокращением), то ввести hte всё равно можно, делая паузы после нажатий (если выставлен флаг timeout, по умолчанию это так). К сокращениям всё это тоже относится. Время, которое Вим ждет, определено в опции timeoutlen, по умолчанию это 1000 (миллисекунд).

Теперь немного нюансов для продвинутых.

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

imap ht fortnight

то ... спастись можно через <C-C>. Впрочем, число "оборотов" всё равно конечно и задано в опции maxmapdepth.

В середине привязка тоже сработает, но не в начале. Так что

imap fo fortnight

безопасно. Только помните, что именно для таких вещей удобнее сокращения и помните, что в этом случае fo всегда будет раскрываться, и вы этого и хотите.

Есть семейство команд для привязок без рекурсии: типа noremap (inoremap и так далее). Некоторые пользуются только ими, оставляя обычные команды на тот случай, если рекурсия зачем-то понадобится. Бывают случаи, хотя и редко. Есть опция-флаг remap, которая по умолчанию включена и позволяет рекурсию. Отключать ее официально не рекомендуется — только для старых скриптов. Дело в том, что она отменяет и "двойную рекурсию".

Рекурсия может быть и двойная, то есть поменять местами команды можно только через noremap:

:noremap k j
:noremap j k

Команда map для этого не годится, так как при нажатии k сработает привязка для j и обратно.

Вот такая "взаимная" рекурсия порой бывает полезна. Пример рассмотрим в другой раз.

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

map <F3> 3w

то есть по нажатию F3 мы будем прыгать на три слова. Если мы поставим повторитель 4, то есть нажмем 4 и сразу после F3, то прыгнем на 43 слова. Потому что технически мы нажали 4, потом 3w.

Иногда это легко обходится. Например, если у нас

map <F3> 3dw

то есть мы удаляем три слова, то эффект такой же; но достаточно написать

map <F3> d3w

чтобы все работало как надо. Вместо "трижды удали слово" мы написали "удали три слова", и вторая команда умножается без проблем.

Справка предлагает использовать регистр-выражение, чтобы выкрутиться в общем случае:

map <F3> @='3w'<CR>

Команда @= открывает строку-выражение, которое есть 3w и результат его вычисления это эта строка, которая и выполняется. Столько раз, сколько предписывает повторитель.

Ну и последнее: комментарии. Комментарии на той же строке, что создает привязку, ставить нельзя, так как символ начала комментария (это двойная кавычка ") и всё после него будет считаться частью правой части привязки. Если привязка определена в скрипте или в файле .vimrc, комментируйте на отдельной строке над привязкой. Если же вы пишете привязку сходу или копируете в командную строку, комментарий вам ни к чему.

Удачи, коллеги!

Научно-популярные каналы на Дзене: путеводитель
Новости популярной науки12 марта 2022

Наука
7 млн интересуются