How do you detect if a directory is opened(with :edit) in Vimscript? I am lazy loading a file explorer and need it to load it before I open a directory.

One approach I tried using an autocommand that fires on BufRead that calls a function that checks if the current buffer is a directory using isdirectory(), but unfortunately to no avail:

-- call directory checker
vim.cmd[[autocmd BufRead * lua checkDir()]]
-- function to check if the file being edited is a directory
-- it also sends a call to my plugin manager to load my file explorer(vim-dirvish)
function checkDir()
  if vim.fn.isdirectory('%') == 1 then
    -- load file manager

2 Answers 2


Supplying a % as an argument to a function will not work. It only expands for Ex commands that expect a filename, like edit (see :help cmdline-special). To prove it, try running echo % or ec string(%) as an Ex command.

If you want to use the current filename as an argument to a function, you must use the expand function and pass it a string corresponding to the thing you want to expand. (See :help expand().)

Try this:

autocmd! BufRead * call CheckDir()

function! CheckDir()
  if isdirectory(expand('%'))
  " load file explorer

Note: the NerdTree plugin messes with this for me because it overwrites the filename and is always identified as not being a directory.

EDIT: Noticed some other things. User-defined functions generally need to start with a capital letter. Also, a function call by itself is not an Ex command. You need to use call CheckDir() (I added it in my code sample above).

  • Thank you for your detailed answer! You are right about some of the mistakes in my Vimscript. I originally wrote the code in Lua but wrote it in Vimscript in my question assuming a wider audience would be able to help me. My Lua code is valid so I will edit my question to incorporate that.
    – unrealapex
    Jan 26, 2023 at 5:04
  1. It doesn't work, because BufRead is triggered after a file was read, while a directory is not a (regular) file and, hence, Vim doesn't even try to (and this is surely told at :h BufRead which you're supposed to read first). The only exception is when BufRead generated forcefully by some script, for example, a plugin, which is still not there.

  2. Plugins normally use autoload feature at some extent. So, as a matter of fact, you're going to double one (smaller) part to autoload another (larger) part which is autoloaded anyway. This is just pointless.

  3. As for actual implementation, most plugins, AFAIK, simply re-check initialization at every BufEnter. It doesn't mean there's no other way though. For example, I opted for BufNew followed by BufReadCmd for my plugin. But this only matters if one attempts to write "a file manager" from scratch.

  • BufReadCmd works well, but the only downside is that it prevents the buffer from being read and I have to read it manually. Are there any other commands that I could use?
    – unrealapex
    Jan 26, 2023 at 5:27
  • @UnrealApex BufReadCmd needs to be defined only for few buffers, those which Vim cannot read itself anyway.
    – Matt
    Jan 26, 2023 at 8:10

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.