GitHub - nathom/filetype.nvim: A faster version of filetype.vim (original) (raw)

This plugin is no longer needed as the optimization has been merged into Neovim core. It is only here for archival purposes.

filetype.nvim

Easily speed up your neovim startup time!

What does this do?

This plugin is a replacement for the included filetype.vim that is sourced on startup. The purpose of that file is to create a series of autocommands that set the filetype variable depending on the filename. The issue is that creating autocommands have significant overhead, and creating 800+ of them as filetype.vim does is a very inefficient way to get the job done.

As you can see, filetype.vim is by far the heaviest nvim runtime file

13.782 [runtime] - 9.144 /usr/local/Cellar/neovim/0.5.0/share/nvim/runtime/filetype.vim 1.662 /usr/local/Cellar/neovim/0.5.0/share/nvim/runtime/plugin/matchit.vim 0.459 /usr/local/Cellar/neovim/0.5.0/share/nvim/runtime/syntax/synload.vim 0.388 /usr/local/Cellar/neovim/0.5.0/share/nvim/runtime/plugin/netrwPlugin.vim 0.334 /usr/local/Cellar/neovim/0.5.0/share/nvim/runtime/plugin/gzip.vim 0.251 /usr/local/Cellar/neovim/0.5.0/share/nvim/runtime/plugin/rplugin.vim 0.248 /usr/local/Cellar/neovim/0.5.0/share/nvim/runtime/syntax/syntax.vim 0.216 /usr/local/Cellar/neovim/0.5.0/share/nvim/runtime/plugin/tarPlugin.vim 0.205 /usr/local/Cellar/neovim/0.5.0/share/nvim/runtime/plugin/zipPlugin.vim 0.186 /usr/local/Cellar/neovim/0.5.0/share/nvim/runtime/syntax/syncolor.vim 0.173 /usr/local/Cellar/neovim/0.5.0/share/nvim/runtime/plugin/matchparen.vim 0.123 /usr/local/Cellar/neovim/0.5.0/share/nvim/runtime/plugin/shada.vim 0.114 /usr/local/Cellar/neovim/0.5.0/share/nvim/runtime/plugin/tohtml.vim 0.075 /usr/local/Cellar/neovim/0.5.0/share/nvim/runtime/plugin/man.vim 0.056 /usr/local/Cellar/neovim/0.5.0/share/nvim/runtime/ftplugin.vim 0.048 /usr/local/Cellar/neovim/0.5.0/share/nvim/runtime/indent.vim 0.039 /usr/local/Cellar/neovim/0.5.0/share/nvim/runtime/plugin/spellfile.vim 0.038 /usr/local/Cellar/neovim/0.5.0/share/nvim/runtime/plugin/tutor.vim 0.022 /usr/local/Cellar/neovim/0.5.0/share/nvim/runtime/plugin/health.vim

filetype.nvim fixes the issue by only creating a single autocommand that resolves the file type when a buffer is opened. This method is ~175x faster*!

Usage

First, install using your favorite package manager. Using packer:

use("nathom/filetype.nvim")

If using a Neovim version earlier than 0.6.0, add the following to init.lua

-- Do not source the default filetype.vim vim.g.did_load_filetypes = 1

That's it! You should now have a much snappier neovim experience!

Customization

filetype.nvim allows you to easily add custom filetypes using the setup function. Here's an example:

-- In init.lua or filetype.nvim's config file require("filetype").setup({ overrides = { extensions = { -- Set the filetype of *.pn files to potion pn = "potion", }, literal = { -- Set the filetype of files named "MyBackupFile" to lua MyBackupFile = "lua", }, complex = { -- Set the filetype of any full filename matching the regex to gitconfig [".*git/config"] = "gitconfig", -- Included in the plugin },

    -- The same as the ones above except the keys map to functions
    function_extensions = {
        ["cpp"] = function()
            vim.bo.filetype = "cpp"
            -- Remove annoying indent jumping
            vim.bo.cinoptions = vim.bo.cinoptions .. "L0"
        end,
        ["pdf"] = function()
            vim.bo.filetype = "pdf"
            -- Open in PDF viewer (Skim.app) automatically
            vim.fn.jobstart(
                "open -a skim " .. '"' .. vim.fn.expand("%") .. '"'
            )
        end,
    },
    function_literal = {
        Brewfile = function()
            vim.cmd("syntax off")
        end,
    },
    function_complex = {
        ["*.math_notes/%w+"] = function()
            vim.cmd("iabbrev $ <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow></mrow><annotation encoding="application/x-tex"></annotation></semantics></math></span><span class="katex-html" aria-hidden="true"></span></span>")
        end,
    },

    shebang = {
        -- Set the filetype of files with a dash shebang to sh
        dash = "sh",
    },
},

})

The extensions and literal tables are orders faster than the other ones because they only require a table lookup. Always try to use these before resorting to the complex tables, which require looping over the entries and running a regex for each one.

Performance Comparison

These were measured using startuptime.vim

Without filetype.nvim

Average startup time (100 rounds): 36.410 ms

Sample log

times in msec clock self+sourced self: sourced script clock elapsed: other lines

000.008 000.008: --- NVIM STARTING --- 000.827 000.819: locale set 001.304 000.477: inits 1 001.358 000.054: window checked 001.369 000.011: parsing arguments 002.537 001.168: expanding arguments 002.626 000.089: inits 2 002.998 000.372: init highlight 012.731 000.961 000.961: sourcing /Users/nathan/.local/share/nvim/site/pack/packer/start/vim-gruvbox8/colors/gruvbox8.vim 012.829 009.549 008.588: sourcing /Users/nathan/.config/nvim/init.lua 012.837 000.290: sourcing vimrc file(s) 019.775 000.035 000.035: sourcing /Users/nathan/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/elixir.vim 019.867 000.026 000.026: sourcing /Users/nathan/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/fish.vim 019.949 000.022 000.022: sourcing /Users/nathan/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/gdresource.vim 020.025 000.017 000.017: sourcing /Users/nathan/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/gdscript.vim 020.108 000.018 000.018: sourcing /Users/nathan/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/gomod.vim 020.194 000.029 000.029: sourcing /Users/nathan/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/graphql.vim 020.280 000.029 000.029: sourcing /Users/nathan/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/hcl.vim 020.358 000.021 000.021: sourcing /Users/nathan/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/heex.vim 020.436 000.021 000.021: sourcing /Users/nathan/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/json5.vim 020.517 000.024 000.024: sourcing /Users/nathan/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/julia.vim 020.601 000.028 000.028: sourcing /Users/nathan/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/ledger.vim 020.680 000.022 000.022: sourcing /Users/nathan/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/nix.vim 020.764 000.028 000.028: sourcing /Users/nathan/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/ql.vim 020.851 000.031 000.031: sourcing /Users/nathan/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/query.vim 020.933 000.025 000.025: sourcing /Users/nathan/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/surface.vim 021.127 000.031 000.031: sourcing /Users/nathan/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/teal.vim 021.218 000.025 000.025: sourcing /Users/nathan/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/tlaplus.vim 021.301 000.023 000.023: sourcing /Users/nathan/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/yang.vim 021.382 000.023 000.023: sourcing /Users/nathan/.local/share/nvim/site/pack/packer/start/nvim-treesitter/ftdetect/zig.vim

With filetype.nvim

Average startup time (100 rounds): 26.492 ms

Sample log

times in msec clock self+sourced self: sourced script clock elapsed: other lines

000.008 000.008: --- NVIM STARTING --- 000.813 000.805: locale set 001.282 000.470: inits 1 001.334 000.052: window checked 001.345 000.011: parsing arguments 002.386 001.041: expanding arguments 002.459 000.073: inits 2 002.859 000.400: init highlight 013.346 001.066 001.066: sourcing /Users/nathan/.local/share/nvim/site/pack/packer/start/vim-gruvbox8/colors/gruvbox8.vim 013.471 010.343 009.276: sourcing /Users/nathan/.config/nvim/init.lua 013.485 000.283: sourcing vimrc file(s)

* The time my machine takes to source the file goes from 9.1 ms to (0.022 + 0.03) ms, which is a 175x speedup.

Contributions

All contributions are appreciated! But please make sure to follow these guidelines: