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.
- You want to designate files with a certain extension as having a file type that Vim knows.
- 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:
- Create your user runtime directory. You would normally use the first item of the 'runtimepath' option.
- Create the directory "ftdetect" inside that.
- 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
- 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":
- 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.
- 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
.
- 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!
- 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".
- Everyone else is doing it that way so I will, too! ;)