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?

3 Answers 3


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
    Commented May 4, 2021 at 12:08
  • 1
    @statox If there could be more than two of them then I would do it also.
    – Matt
    Commented May 4, 2021 at 12:10
  • Can you provided a short script to automatically set filetype to text if typeless? Commented May 5, 2021 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
    Commented May 5, 2021 at 6:48
  • @Matt, This works for existing files, such as README or TODO, but not if you open Vim with a new empty buffer or if you create a new empty buffer by using :enew. Could you improve the current version?
    – john c. j.
    Commented Aug 24, 2022 at 12:12

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
    Commented May 4, 2021 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
    Commented May 4, 2021 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
    Commented May 4, 2021 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
    Commented May 4, 2021 at 10:22

I'm assuming you don't want these autocmds to run on every file without a filetype and that there's some condition for when it should execute.

The built-in way to detect extensionless files is described in RECOGNIZING BY CONTENTS in :help filetype-plugin. It's down at the bottom:

If your file cannot be recognized by its file name, you might be able to recognize it by its contents. For example, many script files start with a line like:

  #!/bin/xyz ~

To recognize this script create a file "scripts.vim" in your runtime directory (same place where filetype.vim goes). It might look like this:

  if did_filetype()
  if getline(1) =~ '^#!.*[/\\]xyz\>'
    setf xyz

You can even have multiple scripts.vim files in different runtimepath folders (so plugins can use scripts.vim).

Using scripts.vim would let you inspect the content to determine what filetype the file should have and then you can use the FileType autocmd to trigger.

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.