Vim: экранирование "бара", объединяющего команды Ex - PullRequest
5 голосов
/ 14 марта 2012

Я не понимаю, почему эти команды делают разные вещи.

Вставляется в файл vimrc, активируется нажатием t в обычном режиме:

nnoremap t :call search('\m\(a\|b\)', 'W')<CR>
nnoremap t :call search('\m\(a\\|b\)', 'W')<CR>

Набирается непосредственно в командной строке:

:call search('\m\(a\|b\)', 'W')
:call search('\m\(a\\|b\)', 'W')

Чтобы быть точным: «предполагаемое» поведение требует \\| в примере nnoremap, но оно требует \| в call примере поиска.

Я знаю, что специальная обработка бара (:help :bar) - одна из тех ловушек, которые Вим устроила для меня, но она все еще не имеет смысла. В документации четко сказано, что «этот список команд будет видеть строку как часть их аргумента», но ни одно из этих исключений здесь не применимо. Все команды, включенные в этот пример, обрабатывают бар как символ мета-конкатенации. Также в этой ситуации панель находится внутри строки и (я думаю?), Анализируемая как часть строки, имеет приоритет над синтаксисом мета-конкатенации.

Ответы [ 2 ]

11 голосов
/ 14 марта 2012

Действительно, проблема вызвана особой обработкой символа команды создания карт.

Механизм сопоставления клавиш в Vim - это способ выполнения последовательности нажатий клавиш. быть интерпретированным как другая последовательность ключей; нет семантической интерпретации Язык сценариев Vim сделан на этом уровне. Так как для создания отображения это необходимо разделить оба аргумента последовательности ключей, чтобы установить соответствие между командами :map -семейства начинаются с определения границ эти два аргумента. Чтобы использовать символы, которые могут помешать этому процесс в отображении, необходимо использовать экранирующий синтаксис, предусмотренный для этого символы (среди которых возврат каретки, пробел, обратная косая черта и строка).

Поскольку символ бара можно использовать для отделения команды отображения от следующую команду Ex и, таким образом, определить конечную границу с правой стороны сопоставления, его нельзя использовать как есть в последовательности клавиш. Согласно :help map_bar, в зависимости от настроек, символ бара может быть экранированный как <bar>, \| или ^V| (где ^V обозначает буквальный Ctrl + V код клавиши).

Имея это в виду, давайте проследим рассматриваемые отображения (вокруг \| / \\| часть) как они интерпретируются в конфигурации по умолчанию. В В первом сопоставлении последовательность \| обрабатывается как один символ |. Следовательно, после выполнения этой команды сопоставления нажатие t будет так же, как печатать

:call search('\m\(a|b\)', 'W') Введите

Когда запускается вторая команда отображения, строка \\| интерпретируется как буквенный символ обратной косой черты (нет необходимости экранировать \ в справа от отображений, кроме вложенных), за которыми следует \| спецификатор, представляющий символ бара. Итак, эта команда отображает t на следующее:

:call search('\m\(a\|b\)', 'W') Введите

Однако при вводе сопоставленных поисковых запросов в режиме командной строки, в отличие от последовательности клавиш в отображениях, они сразу же интерпретируются как команды Ex. Эти штриховые символы встречаются в строковых литералах, поэтому нет возможности неправильно интерпретировать их как разделители для команд Ex. При прямом наборе, Команды отправляются на выполнение, как они написаны. Таким образом, разница в работе между ними из-за значения регулярных выражений \m\(a\|b\) и \m\(a\\|b\), не из-за побега.

7 голосов
/ 14 марта 2012

Когда вы используете команды vim *map и command, механизм vimscript не интерпретирует команду - он сохраняет ее как есть, в виде последовательности нажатий клавиш (в случае *map) или в виде строки (в дело command). Команда интерпретируется только при ее использовании.

Из-за этого, когда вы отображаете команду, vim на самом деле не знает, что ваш символ канала находится внутри строки, потому что он не знает и не заботится, есть ли строки в вашей команде, по крайней мере, на этом этапе.

Если вы хотите использовать | в *map, вам нужно использовать <bar>.

...