Introducing filetype.lua and a call for help

I’m excited to announce that earlier today we merged a new feature for providing filetype detection in Lua.

Background

What exactly is “filetype detection”? Have you ever wondered how exactly Neovim knows the filetype of the file you’re working on? When you start Neovim, after your init.vim or init.lua is started, Neovim runs the equivalent of :filetype plugin indent on (this line is necessary in your .vimrc when using Vim, but Neovim does it automatically for you). When this command runs, it sources the file $VIMRUNTIME/filetype.vim (among others). If you open up that file you will find almost 2500 lines of autocommands whose job it is to determine the filetype of a file based on the file’s name. Many autocommands rely on the file’s extension, but many others also look at other parts of the file path. Some of these autocommands even use functions or other scripting features to disambiguate between two possible filetypes.

So what’s the problem?

Well, creating thousands of autocommands on startup is not exactly very performant. Indeed, filetype.vim is one of the slowest (perhaps the slowest) startup files shipped with Neovim. An alternative approach is to create one single BufNewFile,BufRead * autocommand that fires on every new file and then dispatches a function to determine the filetype.

This is the approach filetype.lua takes, which means that it is considerably more performant than filetype.vim. We also gain all the other benefits of Lua; namely, anonymous functions, closures, and fast table lookups.

How do I use it?

filetype.lua is currently opt-in, so it will not be enabled unless you explicitly enable it yourself. You can do so by adding the following to your init.vim/init.lua (or you can create a new filetype.lua file and add it there: the result is the same):

let g:do_filetype_lua = 1

The do_filetype_lua global variable activates the Lua filetype detection mechanism, which runs before the legacy Vim script filetype detection. Note that this does not disable the existing filetype detection checks! This means that you will be using both Lua and Vim script filetype detection, which will actualy increase your startuptime. This is necessary for now simply because filetype.lua does not yet have parity with filetype.vim, so there are some filetypes that filetype.lua will not successfully detect.

If you want to disable filetype.vim and use only filetype.lua (at your own risk), you can add the following to your init.vim:

let g:did_load_filetypes = 0

A value of 0 for this variable disables filetype.vim. A value of 1 disables both filetype.vim and filetype.lua (which you probably don’t want).

Call for help

We need testers! If you are willing, please opt-in to Lua filetype detection and let us know if you find any issues. If you choose to disable the legacy filetype.vim detection and come across a filetype that filetype.lua does not correctly detect, consider creating a PR to port those changes into filetype.lua. This is a fairly straightforward task and is new-contributor-friendly, so if you’ve been looking for a chance to get involved in Neovim development, this could be it!


I would be remiss to not give honorable mention to @nathom’s filetype.nvim plugin. The implementation in Neovim is 100% our own, but @nathom’s plugin helped spur this conversation and provided the motivation to add this feature upstream. Thanks @nathom!

If you’re curious, you can find more discussion around the implementation in the PR.

Thanks!

24 Likes