0

I'm writing my first Vim/Neovim plugin, which improves support for files managed by yadm. Pretty straightforward.

However, while reading other plugins for inspiration, I have noticed that plugin authors almost never use the filetypedetect augroup to group autocmds that set filetypes. For example, fish-vim, vim-jsx-typescript, vim-toml, haskell.vim, and vim-javascript all omit the filetypedetect augroup, despite the fact that the filetypedetect augroup is recommended on the Vim Tips Wiki and even the built-in documentation (:help 43.2).

Why do plugin authors not use the filetypedetect augroup? Should the filetypedetect augroup be used in plugins to group autocmds that set filetypes?

0

1 Answer 1

2

Well, we're looking at two different cases with the examples you provided: when the file type is recognized by Vim and when it's not. Combined with the fact that Vim gives you four ways to deal with file types that haven't yet been identified and some confusion is understandable.

Before answering the question of why the filetypedetect method isn't used, let's step back and look at that method and the alternative method seen in the plugins.

filetypedetect is typically used to detect file types that Vim doesn't already recognize, i.e. it has no detection for the file type built in. With this method, the file extension must be enough to determine whether a file matches. You'll need to add your detection code as an autocommand within the autocommand group named filetypedetect and put all this in a file named filetype.vim.

Vim's help suggests there's just one appropriate place for filetype.vim: under the first directory found in the 'runtimepath' setting. That usually means $HOME/.vim on *nix systems and $USER/vimfiles on Windows.

For example, if Vim didn't know what Florg files were (I don't either!) one might add the following to $HOME/.vim/filetype.vim:

augroup filetypedetect
  au! BufRead,BufNewFile *.florg set filetype=florg
augroup END

By itself, though, this doesn't accomplish much so let's divide this up into a couple use cases.

  1. You want to designate files with a certain extension as having a file type that Vim knows.
  2. You want to define a new file type altogether.

In the first case let's say, for example, that you want to edit files with extension .pyz as Python files. You could just do exactly as outlined in the florg example, above. With .pyz files branded as Python all the existing syntax highlighting, indentation, and installed Python plugins will now be applied.

In the second case we need to do something different since adding an entry to $HOME/.vim/filetype.vim doesn't do anything except set 'filetype' to "florg". What you're probably going to want to do is implement a plugin and in that case your filetype.vim is going to be in the plugin's root directory.

Yes, you can put filetype.vim in other places. As long as the directory it resides in is found in 'runtimepath' it will get sourced.

Okay, but all of the above is not the same as wanting to override Vim's built-in handling of a filetype. That's what several of the example plugins you listed are doing. Vim recognizes Haskell files but the author of the plugin haskell.vim didn't think it was doing enough to make editing haskell files convenient (or something like that). So they decided they'd take matters into their own hands.

If you look at :h new-filetype you'll find the text If you want to overrule all default file type checks... followed by instructions that I'll summarize:

  1. Create your user runtime directory. You would normally use the first item of the 'runtimepath' option.
  2. Create the directory "ftdetect" inside that.
  3. Create a file that contains an autocommand(s) to detect the file type. Example (note lack of "augroup", file contents are implicitly wrapped when the file is sourced):
    au BufRead,BufNewFile *.mine set filetype=mine
  1. To use the new filetype detection you must restart Vim. The files in the "ftdetect" directory are used after all the default checks, thus they can overrule a previously detected file type.

Looking at the Haskell plugin you mentioned they do exactly as described. The file is {plugin}/ftdetect/haskell.vim. It contains lines like this one:

au BufRead,BufNewFile *.hsc set filetype=haskell

Most of the others you mentioned do the same. That includes the fish and toml associated plugins. But Vim doesn't recognize those as file types. So why aren't they using the filetypedetect approach?

We've come full circle to the actual question being asked. I will give several reasons starting with probably the most important and moving from there to a few more "cosmetic reasons":

  1. You want your plugin to be as robust as possible. So you'll want to design it in such a way that it continues to work if Vim does add support for your file type in the future. Thus, the best choice is the approach Vim's documentation specifies as being used to overrule default checks.
  2. With ftdetect you can put both filename- and content- based file type discovery code in one place. The other method requires two files: filetype.vim and script.vim.
  3. Putting code or configuration in the root of your plugin directory (never mind the root of your $HOME/.vim tree) is strange and goes against common convention. There are sub-directories for that kind of thing!
  4. Though Vim's help suggests that it's a pain to have one file per file type when using the ftdetect method, that actually appeals to people who like organized code and things like "separation of concerns".
  5. Everyone else is doing it that way so I will, too! ;)
2
  • 1
    What a detailed answer. Thank you! You inspired me to do a few more deep-dives of the new-filetype documentation. As you say, it's a bit confusing, but you helped me make sense of it. Much appreciated. Jun 25, 2021 at 4:34
  • 1
    @JohnKarahalis I'm glad you found it useful and I appreciate the comment. Believe it or not I felt it needed a bit more depth LOL so take a look at the updated edition. I probably overdid it. :D Cheers.
    – B Layer
    Jun 25, 2021 at 8:46

Your Answer

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

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