Найти тему
Блокнот математика

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

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

Ну  типа режимы и привязки))  [https://avatars.dzeninfra.ru/get-zen_doc/1639101/pub_5decb7768d5b5f0c74c80175_5decbc87dddaf400af8fa5ea/scale_1200]
Ну типа режимы и привязки)) [https://avatars.dzeninfra.ru/get-zen_doc/1639101/pub_5decb7768d5b5f0c74c80175_5decbc87dddaf400af8fa5ea/scale_1200]

Теперь вспомним о режимах. Режимов много, помимо основных: нормального и вставки, есть еще командная строка (включая и поиск), где не всегда нужны те же привязки, что и в режиме вставки, а еще режим выделения и другие. Вы можете создавать привязки для каждого режима отдельно. Давайте рассмотрим весь арсенал команд. Всегда в указанной командой идет парная ей noremap и отменяющая ее unmap. У всех одна и та же буква вначале: imap, inoremap, iunmap и всё в таком роде.

Команда map создает привязку для нормального режима, режима выделения, режима классического выделения и режима ожидания движения (это когда вы нажали d и Вим ждет указания, докуда удалять текст).

Создать (или отменить) привязку только для нормального режима позволяет nmap (nunmap, по поводу которой Справка шутит: "nunmap can be used outside the monastery"; юмор в том, что map это карта, а nun — монахиня).

Для обоих визуальных режимов есть vmap. Либо по-отдельности: xmap для выделения, smap для классического выделения.

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

Для операторного режима есть отдельная команда omap. Операторный режим — это когда вы нажали d или y и Вим ждет команду движения. Вот для этой ситуации можно создать особую привязку!

Для режима вставки, как уже обсуждалось, imap.

Для командной строки cmap.

Есть и пакетная команда: map! Да, с восклицательным знаком она создает привязки для режима вставки И командной строки. В общем-то, можно парой map и map! обойтись.

Ещё есть вариант lmap, который создает привязки для режимов вставки и командой строки, а ещё для особого псевдорежима: когда мы вводим часть команды, являющуюся текстом. Например, после команды r (замена символа под курсором) надо указать новый символ: вот после r, но до этого символа, и есть этот "режим". Ещё примеры — f, t и т.п.

Отдельно для этого псевдорежима команды нет, но можно применить метод вычитания: выполнить lmap и затем cunmap и iunmap.

Есть серия команд типа :tmap — для терминала.

Про особые символы. Включить пробел в левую часть привязки можно хитрым способом: через вставку спецсимволов. Мы знаем, что <C-V> позволяет вставить спецсимволы, такие как <ESC> или <CR>, а мы вставим ее саму (нажав <C-V> дважды). Получим нечто, что будет выглядеть как ^V. Затем поставим пробел. Вим поймет, что надо ожидать литерального пробела. Например,

imap 1 2 раз два

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

imap 1^V 2 раз два

и теперь это работает правильно: если без пауз нажать "1 2", то получим "раз два".

В правую часть пробел включить можно тем же способом, либо через последовательность <space>.

Другие такие коды тоже можно использовать, например <CR> для клавиши ввода.

Еще одна полезная последовательность для правой части — <nop>. Она ничего не делает. Что-то вроде нуля для привязок. Можно сделать много привязок, проверить, что они без ошибок и не конфликтуют, а потом задать спокойно правые части, причем можно не сразу все.

Теперь поговорим о конвейере. Конвейером не совсем правильно мы называем символ |, который просто позволяет выполнять команды одна за другой (конвейер в смысле UNIX передает выход одной команды на вход другой).

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

map <F2> :w<CR> | echo 'saved'

выполнит не то, что мы замыслили: создаст привязку, которая сохраняет файл по <F2> и потом выведет сообщение. А мы хотели, чтобы по нажатию <F2> файл сохранялся и об этом выводилось сообщение.

Есть три способа достичь задуманного. Универсальный способ есть: ввести черту литерально, через <C-V>. Сначала вводим саму эту комбинацию, нажав C-V> дважды, а потом черту. Но это неизящно. Зато всегда работает.

Второй способ — экранировать черту слешем: \|. Это логично и последовательно, но может не работать, если в cpoptions присутствует флаг b. По умолчанию его там нет.

Третий способ — использовать описательную комбинацию <Bar>. Это тоже логично, но может не работать, если в cpoptions присутствует флаг < (которого по умолчанию нет и который отключает вообще все такие описательные комбинации в уголках).

Все три способа работают, если cpoptions по умолчанию. Напомню, что это опция флагов совместимости, то есть позволяет приблизить Вим к vi (поведение которого не всегда логично, но исторически так повелось), если вам это реально надо.

Еще напомню, что можно легко вернуться к значению по умолчанию:

:set cpoptions&

Можете предварительно сохранить состояние:

:let save_cpoptions=&cpoptions

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

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