I'm struggling with strange case. I've read many help pages and search through net but found nothing.

In my vimrc:

function! s:rename(name)
        echom a:name
        saveas a:name
        " bd #
        " silent !rm #
command! -nargs=1 Ren call s:rename(<f-args>)

In a file:

:Ren newname

"a:name" 4L, 9C written

Why a:name is not recognized as a variable!?


:saveas expects a filename as an argument (see :h :saveas).

So, inside your function, when you pass a:name to :saveas, it treats it as a filename.
If you want to pass the contents of the variable a:name, you can write this:

execute 'saveas ' . a:name

The difference is that :execute expects an expression (see :h :execute).
'saveas ' is a string, which is a type of expression.
a:name is a variable, which here is replaced with its contents.
It's the same kind of evaluation you see when you type:

:let myvar = 'hello'
:echo myvar

myvar is automatically evaluated into its value after :echo, just like after :execute, but not after :saveas. Because, again, the first 2 commands expect expressions as arguments, whereas the latter expects a filename.

The evaluation of a:name is a string which contains your filename, and the dot between saveas and a:name is the concatenation operator (see :h expr-.). The result of the concatenation is again a string which is still a kind of expression.

So, :execute receives an expression as an argument, which is what it expects, and executes it as an Ex command.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.