Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vim - writing to filename in vimscript variable

Tags:

vim

I'm doing something like

:let foo="bar"
:echom foo
bar
:w foo
"foo" [New File] 0 lines, 0 characters written

I am expecting/hoping to write a file named "bar", not a file named "foo". Assuming that I have a string stored in a variable "foo", how can I write the current buffer to a file with the name being that string?

As an aside, can someone explain what :w foo and :echom foo are doing different with regards to foo?

like image 393
Bakkot Avatar asked May 26 '14 04:05

Bakkot


2 Answers

Vimscript evaluation rules

Vimscript is evaluated exactly like the Ex commands typed in the : command-line. There were no variables in ex, so there's no way to specify them. When typing a command interactively, you'd probably use <C-R>= to insert variable contents:

:sleep <C-R>=timetowait<CR>m<CR>

... but in a script, :execute must be used. All the literal parts of the Ex command must be quoted (single or double quotes), and then concatenated with the variables:

execute 'sleep' timetowait . 'm'

Like :execute above, the :echo[msg command is particular in that it takes a variable argument, whereas most commands (like :write) do not, and treat the argument(s) literally.

Your particular problem

As above, your issue is best resolved via execute:

:execute 'write' foo

However, note that if foo contains any regular filename, it still needs to be escaped for the :write function, which understands some special notation (e.g. % stands for the current buffer name), and likes to have spaces escaped:

:execute 'write' fnameescape(foo)
like image 121
Ingo Karkat Avatar answered Sep 30 '22 20:09

Ingo Karkat


Only

:execute 'write ' . foo<CR>

and

:write <C-r>=foo<CR><CR>

do what you want.

Variables can be used in a concatenation, case 1, or in an expression, case 2.

like image 38
romainl Avatar answered Sep 30 '22 18:09

romainl