Reputation: 8076
In Vim, I can echo the current filename using this command:
:echo @%
I found that information here: http://vim.wikia.com/wiki/Get_the_name_of_the_current_file
Can someone explain why the @
symbol is necessary? If I enter the command without the @
symbol, I get an error:
E15: Invalid expression: %
E15: Invalid expression: %
However, if I try to send the filename to a bang
command as an argument, including the @
sign appears as a regular character in the argument. Removing the @
sign works. In other words, in my .bash_profile
I have the following function:
test_func() {
echo $1
}
In Vim, I run:
:! test_func @% #outputs @path/to/my/file
:! test_func % #outputs path/to/my/file
What is the @
symbol doing and why does it behave differently when sending the output to a bash function?
Upvotes: 11
Views: 5575
Reputation: 172570
:echo
takes a Vimscript expression, whereas :!
takes and external command, which is a special case for a filename, which is accepted by :edit
et al.
For external commands and filenames, there are special characters such as %
and #
, described under :help cmdline-special
. This also includes this crucial sentence:
In Ex commands, at places where a file name can be used, the following characters have a special meaning.
In contrast, :echo
does not take a filename, but an expression. There are several ways to resolve the current filename; the most direct is via expand()
:
:echo expand('%')
Alternatively, as the current filename is also stored in a special register %
, and registers are addressed via the @
sigil:
:echo @%
This also explains the frequent question of why :edit g:variable
doesn't work as expected. Vim's evaluation rules are different than most programming languages. You need to use :execute
in order to evaluate a variable (or expression); otherwise, it's taken literally; i.e. Vim uses the variable name itself as the argument.
Upvotes: 10
Reputation: 80931
I believe that is :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.
As to why you don't need that for :!
that is probably because of :h cmdline-special
.
- 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_%
Upvotes: 5