I want some autocmds to run when I open a file without a filetype like nvim (no file name) or nvim myfile (no extension). I also want them to run when opening certain file types like text and markdown so I can't blacklist everything with a file type/extension. Is there a way to run certain autocmds when no file type is known?


You can use the value of &filetype to determine if you are in a buffer without a filetype or with one of the filetype you want to target. One example could be like this:

function! DoStuff()
    if (exists('b:StuffDone') || index(['', 'text', 'markdown'], &ft) < 0)
    let b:StuffDone = 1

    echo "Doing stuff for" &ft

augroup Test
    autocmd BufEnter * call DoStuff()
augroup END

Here your autocommand will call the function DoStuff() for all of your buffers, however the function itself will check the current filetype and stop its execution if the filetype is not empty and if it's not in the list of filetypes you want to handle.

As @Matt pointed out in the comments BufEnter is triggered each time you enter the buffer so that might be an issue. However reading :h autocmd-events I don't find an event which would trigger for all buffers after we have their filetype. To prevent running your code several time in the same buffer I set a variable b:StuffDone which is local to the buffer (:h b:) and test for its existence before running the code.

  • 1
    BufEnter is triggered every time a buffer becomes active. So it feels very wrong to use it for such task.
    – Matt
    May 4 at 8:39
  • @Matt that's a good point, the issue is that the other event might not be triggered for unnamed buffers. So I updated the code with a guard to avoid running the code twice.
    – statox
    May 4 at 8:59
  • This should work, though personally I'd rather create ftdetect/stuff.vim with something like if !did_filetype() || &ft is# 'text' || ....
    – Matt
    May 4 at 9:33
  • 1
    I agree that using the built-in mechanism ftdetect has advantages. Maybe it would be worth it that you post a separate answer with this solution? It's always good to have diversity in the solutions offered to a problem.
    – statox
    May 4 at 10:22

The most accurate and compliant way is to extend filetypes with after/ftplugin/{text,markdown}.vim. Your "no extension" files can probably be detected as "text" filetype as well (or create a completely new filetype if you like). Then the actual functionality should be shared by a common autoloaded script.

But if you don't care then a single ftdetect script can do all work. Sort of,


autocmd BufNewFile,BufRead *
    \    if !did_filetype() && empty(expand("<afile>:e")) || &ft is# "text" || &ft is# "markdown"
    \ |      " do some stuff...
    \ |  endif

Note: FileType for an empty unnamed buffer is not auto-detected. So if you really need to do something in this case you still have to catch VimEnter (or BufNew, or BufEnter etc.).

  • That's probably a "cleaner" way to do it than my answer :+1: (Thought I'd still use a list to check the filetype rather than &ft is# "text" || &ft is# "markdown")
    – statox
    May 4 at 12:08
  • 1
    @statox If there could be more than two of them then I would do it also.
    – Matt
    May 4 at 12:10
  • Can you provided a short script to automatically set filetype to text if typeless?
    – John Zhau
    May 5 at 6:23
  • @JohnZhau Typeless vs noext vs both... You should probably decide what you need exactly and then you'll be able to change condition in the example above yourself.
    – Matt
    May 5 at 6:48

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.