Vim 获取当前文件名的语法

Vim syntax for getting name of current file

在 Vim 中,我可以使用此命令回显当前文件名:

:echo @%

我在此处找到该信息:http://vim.wikia.com/wiki/Get_the_name_of_the_current_file

谁能解释一下为什么需要 @ 符号?如果我输入没有 @ 符号的命令,我会得到一个错误:

E15: Invalid expression: %
E15: Invalid expression: %

但是,如果我尝试将文件名作为参数发送到 bang 命令,则包括 @ 符号在参数中显示为常规字符。删除 @ 标志有效。换句话说,在我的 .bash_profile 中,我有以下功能:

test_func() {
        echo 
}

在Vim,我运行:

:! test_func @%    #outputs @path/to/my/file
:! test_func %     #outputs path/to/my/file

@ 符号在做什么,为什么它在将输出发送到 bash 函数时表现不同?

我认为是 :h expr-register:

register expr-register @r


@r contents of register 'r'

The result is the contents of the named register, as a single string. Newlines are inserted where required. To get the contents of the unnamed register use @" or @@. See |registers| for an explanation of the available registers.

When using the '=' register you get the expression itself, not what it evaluates to. Use |eval()| to evaluate it.

至于为什么 :! 不需要它,这可能是因为 :h cmdline-special.

  1. Ex special characters cmdline-special

Note: These are special characters in the executed command line. If you want to insert special things while typing you can use the CTRL-R command. For example, "%" stands for the current file name, while CTRL-R % inserts the current file name right away. See |c_CTRL-R|.

Note: If you want to avoid the special characters in a Vim script you may want to use |fnameescape()|.

In Ex commands, at places where a file name can be used, the following characters have a special meaning. These can also be used in the expression function expand() |expand()|. % Is replaced with the current file name. :_% c_%

:echo 接受 Vim 脚本 表达式 ,而 :! 接受 外部命令,这是文件名的特例,被:edit等人接受

对于外部命令和文件名,有%#等特殊字符,在:help cmdline-special中有说明。这还包括这句关键的话:

In Ex commands, at places where a file name can be used, the following characters have a special meaning.

相比之下,:echo不接受文件名,而是一个表达式。有几种方法可以解析当前文件名;最直接的是通过 expand():

:echo expand('%')

或者,由于当前文件名也存储在特殊寄存器 % 中,并且寄存器通过 @ 标记寻址:

:echo @%

反过来

这也解释了为什么 :edit g:variable 没有按预期工作的常见问题。 Vim 的评估规则与大多数编程语言不同。您需要使用 :execute 来评估变量(或表达式);否则,它是从字面上理解的;即 Vim 使用变量名本身作为参数。