Как я могу избежать символов% и # в команде Vim?

Я использую Ack (https://github.com/mileszs/ack.vim) с флаг --literal для поиска проектов в Vim. Я заметил, что всякий раз, когда я ищу строку с символами % или #, поиск не соответствует вещам, как я ожидал. Я провел некоторое исследование и обнаружил, что это связано с тем, что Vim расширяет эти символы в командах (% — это текущий файл, а # — что-то еще, не знаю, что именно).

Это довольно раздражающее поведение при выполнении поиска, учитывая, что эти символы довольно часто встречаются в коде. Есть ли способ избежать их, желательно автоматически, чтобы поиск работал как положено? Мое текущее отображение: nnoremap <leader>al :Ack --literal<space>.

Пример

Скажем, у меня где-то есть селектор #body в файле CSS, и я хочу его найти. Вот что я пробовал (не помогло):

:Ack --literal #body
:Ack --literal \#body
:Ack --literal "#body"
:Ack --literal "\#body"

Любые идеи, почему побег здесь не работает, как обычно, или что это вообще ищет? Эти примеры не соответствуют чему-либо.

Решение

Я заставил его работать, дважды экранируя символы. Например, :Ack --literal "\\#body" отобразит :ack -H --nocolor --nogroup --column --literal "#body" в строке состояния окна результатов и вызовет ожидаемые результаты. Кавычки тоже нужны.


person John Debs    schedule 14.04.2011    source источник
comment
@ Рэнди Это имеет смысл. Спасибо!   -  person John Debs    schedule 15.04.2011


Ответы (4)


Вы просто ставите перед ними обратную косую черту

:!echo %

выводит имя файла текущего буфера

:!echo \%

печатает одиночный символ '%'

person sehe    schedule 14.04.2011
comment
Спасибо за ответ. Ваш пример работает, как и ожидалось, но я обновил свой вопрос, включив пример, когда этот тип экранирования не работает. Любые идеи относительно того, почему нет / что можно сделать? - person John Debs; 15.04.2011
comment
Вероятно, это ошибка в ack.vim (где он передает ввод без повторного экранирования). Я бы связался с автором / посмотрел, исправляет ли это новая версия - person sehe; 15.04.2011
comment
В Vim версии 8.1 мне приходилось экранировать #, используя двойную косую черту, например \\#, иначе это не сработало. Например, ! echo \# ничего не напечатал, а ! echo \\# напечатал символ решетки. - person RajaRaviVarma; 20.09.2019
comment
@RajaRaviVarma на самом деле ничем не отличается. Это потому, что # является символом комментария оболочки. !echo \# на самом деле отправляет echo # в оболочку. Вы можете легко убедиться, что echo # на самом деле ничего не печатает в оболочках posix. Итак, тайна разгадана. Добавление второй косой черты отправляет echo \# в оболочку. Я бы предложил вместо этого !echo '#' - person sehe; 20.09.2019
comment
Ах! Спасибо @sehe, !echo '#' не сработало, как ожидалось. Но ! echo '\#' сделал. - person RajaRaviVarma; 20.09.2019
comment
Часто, когда что-то работает не так, как ожидалось, это ожидание было ошибочным. - person sehe; 20.09.2019

По-видимому, вам нужно экранировать несколько раз, как указано в проблеме с ack.vim:

:Ack \\\#foo
person brianpeiris    schedule 07.04.2014

Это ошибка в ack.vim, почему-то программа ack даже не вызывается, когда вы делаете :Ack --literal \#body

Однако я использовал

`strace -f -o-e trace=process gvim | tee /tmp/log`

И кажется, что выполнение :Ack --literal '\#body' (обратите внимание на дополнительные кавычки) действительно работает так, как ожидалось:

[pid  3833] execve("/usr/bin/ack", ["ack", "-H", "--nocolor", "--nogroup", "--literal", "#body"], [/* 25 vars */] <unfinished ...>

Я особо не тестировал...

person sehe    schedule 15.04.2011
comment
@John: удалось ли вам использовать этот синтаксис '\#body'? Execve уверен, что это должно работать (но у меня нет подтверждения) - person sehe; 17.04.2011

У меня есть одно дополнение к ответу @sehe: когда вы делаете !... или system('...'), vim не обрабатывает ... сам по себе, а вызывает оболочку, например: {shell} {shellcmdflag} {shellxquote}...{shellxquote}. Для вызова ack это будет что-то вроде ["/bin/bash", "-c", "ack -H --nocolor --nogroup --literal #body"], поэтому bash будет игнорировать все после --literal, потому что # является символом комментария. Для '#body' этого не произойдет, потому что внутри строки в кавычках комментарии невозможны.

person ZyX    schedule 15.04.2011
comment
strace показывает execve. Это не будет вызывать какую-либо оболочку в любой момент. Он будет напрямую вызывать двоичный файл с точными аргументами, разделенными нулем (т.е. без каких-либо расширений) - person sehe; 17.04.2011
comment
@сехе. Да, конечно. Это execve оболочки, а не vim. Поиск назад, вы увидите execve, который вызывает оболочку. - person ZyX; 17.04.2011
comment
@сехе. Или попробуйте объяснить, почему :!trap USR1 не показывает никаких ошибок, а исполняемый файл trap не существует (поскольку trap может быть реализован только как встроенная оболочка). Также см. опцию «shell» и друзья: если vim не вызывает оболочку, то для чего они? - person ZyX; 17.04.2011
comment
Вы упускаете суть. Я показал синтаксис, который (в конечном итоге) запускает execve с правильными параметрами здесь. На этом этапе действительно не имеет значения, сколько уровней оболочки было задействовано. Вызов ack показан правильным в это время. - person sehe; 17.04.2011
comment
@sehe: Это важно: вы объяснили, какой правильный синтаксис, я объяснил, почему он правильный. Если вы найдете где-нибудь оболочку, которая не использует ' в качестве символа кавычек (например, cmd.exe), то это не будет правильным синтаксисом, но мой ответ все равно будет применим и позволит ОП выяснить, в чем проблема . Ваш ответ не будет. - person ZyX; 18.04.2011