开发者

How can I escape the % and # characters in a Vim command?

I'm using Ack (https://github.com/mileszs/ack.vim) with the --literal flag to search through projects in Vim. I noticed that whenever I search for a string with the % or # characters, the search doesn't match things as I'd expect it to. I did some research and found that it's because Vim will expand these characters in commands (% is the current file and # to something else, not sure what).

This is pretty annoying behavior when performing a search, considering these symbols come up pretty often in code. Is there a way to escape them, preferably automatically, so that the search works as expected? My current mapping is: nnoremap <leader>al :Ack --literal<space>.

Example

Say I have a selector #body in a CSS file someplace and I want to find it. These are the things I've tried (that haven't worked):

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

Any ideas why escaping wouldn't work as usual here, or what this is even searching fo开发者_如何转开发r? I haven't had these examples match anything.

Solution

I've gotten it to work by double-escaping the characters. For example, :Ack --literal "\\#body" will show :ack -H --nocolor --nogroup --column --literal "#body" in the statusline of the result window and bring up the expected results. The quotes seem to be required as well.


You just prefix them with a backslash

:!echo %

outputs the current buffer's filename

:!echo \%

prints a solitary '%' character


Apparently you have to escape multiple times as mentioned in an ack.vim issue:

:Ack \\\#foo


I have one addition to @sehe's answer: when you do !... or system('...') vim does not process ... by itself, but calls shell, like this: {shell} {shellcmdflag} {shellxquote}...{shellxquote}. For ack call this will be something like ["/bin/bash", "-c", "ack -H --nocolor --nogroup --literal #body"], so bash will ignore everything after --literal because # is a comment character. It won't do so for '#body' because no comments are possible inside a quoted string.


It is a bug in ack.vim, somehow the ack program isn't even being called when you do :Ack --literal \#body

However, I used

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

And it seems that doing :Ack --literal '\#body' (mind the extra quotes) does work as expected:

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

I haven't really tested it...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜