124

I'm looking for an elegant way in Vimscript to check if a file exists in the current directory.

I came up with the code below but I'm not sure if that's the most elegant solution (I'll set a Vim option if the file exists). Is there any way of not having to do another comparison of the filename?

Maybe use a different built-in function from Vim?

:function! SomeCheck()
:   if findfile("SpecificFile", ".") == "SpecificFile"
:       echo "SpecificFile exists"
:   endif
:endfunction
Matthias Braun
  • 32,039
  • 22
  • 142
  • 171
stefanB
  • 77,323
  • 27
  • 116
  • 141

4 Answers4

155

With a bit of searching in vim man I've found this, which looks much better that the original:

:function! SomeCheck()
:   if filereadable("SpecificFile")
:       echo "SpecificFile exists"
:   endif
:endfunction
stefanB
  • 77,323
  • 27
  • 116
  • 141
  • 5
    What if SpecificFile exists, but is not readable for current user. Maybe findfile is better. – ppan Apr 12 '12 at 09:53
  • 2
    The help for `filereadable` mentions you can use `glob` if you don't care about readability. – Sumudu Fernando Apr 28 '12 at 21:20
  • 10
    if filereadable(expand("~/.vim/bundle/vundle/README.md")) let g:hasVundle = 1 endif – thinker3 Apr 22 '14 at 14:45
  • @metaphy that's an excellent comment, I've added [an answer](https://stackoverflow.com/a/53205873/327074) based on that to give it more visibility, but if you want the credit feel free to add your own answer and I'll delete mine. – icc97 Nov 08 '18 at 10:34
68

Some of the comments express concerns about filereadable and using glob instead. This addresses the issue of having a file that does exist, but permissions prevent it from being read. If you want to detect such cases, the following will work:

:if !empty(glob("path/to/file"))
:   echo "File exists."
:endif
brianmearns
  • 9,581
  • 10
  • 52
  • 79
  • I get `E116: Invalid arguments for function`. How do you specify the file relative to the home directory to check for a plugin? (See also [here](http://stackoverflow.com/a/30444477/3596168)) – Scz Jul 23 '15 at 09:23
  • Are you talking about the user home directory? I would guess just a `~`, but I'm not positive. What arguments did you supply when you got that error? – brianmearns Jul 23 '15 at 10:04
  • 1
    I tried it with `~`, and it gave that error. Now I tried again and it works... :-) – Scz Jul 23 '15 at 13:31
  • 1
    Probably just a typo or something. But glad it worked for you! – brianmearns Jul 23 '15 at 13:34
  • Unlike the other answer, this appears to work for directories, too. – Brian McCutchon Jan 21 '16 at 03:11
  • This also works to expand environment variables where filereadable does not – mrfred Jan 23 '16 at 16:55
  • Note that if the file path is not a constant then it may cause problem with file names contains `*` or `?` on Linux. See `:h wildcard` for details. – user202729 Jan 11 '20 at 11:14
21

Giving some more visibility to metaphy's comment on the accepted answer:

if filereadable(expand("~/.vim/bundle/vundle/README.md")) let g:hasVundle = 1 endif`

filereadable is what is required, if you are using ~ in your file path, there's an extra handy step of expand:

function! SomeCheck()
   if filereadable(expand("SpecificFile"))
       echo "SpecificFile exists"
   endif
endfunction

For example

  • :echo filereadable('~/.vimrc') gives 0,
  • :echo filereadable(expand('~/.vimrc')) gives 1
icc97
  • 11,395
  • 8
  • 76
  • 90
6

Sorry if it's too late, but doing

if !empty(expand(glob("filename")))
    echo "File exists"
else
    echo "File does not exists"
endif

works fine for me

aloussase
  • 61
  • 1
  • 1