7

I can run this snippit of code within a vimscript block:

0read /home/user/.vim/bundle/vim-lorum/lorums/lorum.js

As expected, it puts the contents of "lorum.js" into the current buffer

But, I need to make this a little more dynamic. If I try something like:

let g:filePath="/home/user/.vim/bundle/vim-lorum/lorums/lorum.js"
0read g:filePath

I get this error message:

E484: Can't open file g:filePath

I tried wrapping g:filePath in expand and glob but I get similar errors. Any ideas?

3 Answers 3

9

This is because vim does not evaluate variable names or functions with most commands. In your case, vim thinks you literally want to read the contents of a file called g:filePath into the buffer. What you want can be accomplished with the :execute command. This command takes a string as an argument, and will then run that string as a command. In your case, this is how it would look:

:let g:filePath="/home/user/.vim/bundle/vim-lorum/lorums/lorum.js"
:execute "0read " . fnameescape(g:filePath)

The fnameescape part is just to ensure that all special characters are escaped properly (see :help fnameescape()). For more on how to use :execute, read :help :execute. Also note that . is vim's string concatenation operator.

1
  • Perhaps add a space after 0read? Also wrap g:filePath in a fnameescape()? Commented Jul 21, 2015 at 17:04
6

The solution to this type of problem is the :execute command:

:execute '0read' g:filepath

See

:help :execute
3
  • This is unsafe! You need to escape the filename with fnameescape as explained by @EvergreenTree to prevent vim from expanding it. Try running this code with g:filepath set to `whoami`... Commented Apr 30, 2021 at 19:47
  • True, but it wasn't meant to be a robust solution--it was meant to illustrate the :execute command.
    – garyjohn
    Commented May 2, 2021 at 5:46
  • 1
    Well, yes, but you're kinda illustrating it in an unsafe way. Sooner or later someone is going stumble across your answer and will incorporate your example code into production code without realizing the danger. I was having trouble with a for file in glob loop to source config files from a folder when I found this question, and I was wondering why the top answer used fnameescape while yours was not - maybe yours was safe because it wasn't using string concatenation? I tried it with an unsafe filename and determined that it wasn't safe at all. I commented because this is vital to know. Commented May 2, 2021 at 21:23
6

Commands like read don't evaluate your variables, it takes the argument to be a literal (a file named g:filePath). The execute command, however, takes string arguments, concatenates them and executes the result as if it were a command invocation. You can therefore 'wrap' your command: turn the read command into a string and pass is together with the variable as arguments to execute.

:exe "0read" g:filePath
3
  • I wonder what is the 0 in 0read, the particularities. Commented Jan 6, 2017 at 23:57
  • @SergioAbreu read inserts below the cursor, {range}read inserts below the specified line. Using 0 as the {range} inserts at the top of the buffer.
    – jjaderberg
    Commented Jan 9, 2017 at 12:23
  • And $read to the end :) I got it. Thanks. Commented Jan 9, 2017 at 22:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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