Neovim's Search Directories

We previously looked at the base directories where Neovim looks to find configuration files. Now, lets look at what Neovim searches for in each of these directories.

~/.config/nvim  -- $XDG_CONFIG_HOME
├── plugin/
├── ftplugin/
├── lua/
└── init.lua

When Neovim searches each of these top-level directories, it looks for configuration in each of the following files and sub-directories:

Target Description
filetype.lua filetypes
autoload/ automatically loaded scripts
colors/ color scheme files
compiler/ compiler files
doc/ documentation
ftplugin/ filetype plugins
indent/ indent scripts
keymap/ key mapping files
lang/ menu translations
lua/ Lua plugins
pack/ packages
parser/ treesitter syntax parsers
plugin/ plugin scripts
queries/ treesitter queries
rplugin/ remote-plugins
spell/ spell files
syntax/ syntax files
tutor/ tutorial files

We have highlighted the most common folders in bold, which are:

plugin

The plugin directory contains files that will be executed every time Neovim starts up. When Neovim encounters a plugin sub-directory, it:

  1. collects all files matching *.vim and sources them in alphabetical order, then
  2. collects all files matching *.lua and sources them in alphabetical order, then
  3. collects all sub-directories in alphabetical order and repeats this process, recursively.

ftplugin

The ftplugin directory contains files that may be executed any time Neovim sets a buffer's filetype. A buffer's filetype can be found using:

:lua vim.print(vim.bo.filetype)

When a new buffer is opened Neovim determines the filetype (which we will generically refer to as filetype), then:

  1. Looks for a file filetype.vim and sources it, then
  2. Looks for a file filetype.lua and sources it, then
  3. Looks for any files matching filetype/*.vim and sources them in alphabetical order, then
  4. Looks for any files matching filetype/*.lua and sources them in alphabetical order.
Warning

Keep in mind that files in ftplugin are executed every time a buffer's filetype is set, any scripts must only set buffer-local options. Otherwise, each new buffer will change the configuration of all other buffers.

lua

When you require a module in a Lua script, Neovim looks in the lua directory to source a module with the specified name.

Runtime paths

As you might imagine, recursively traversing so many directories and sub-directories can make it difficult to understand what is getting loaded when Neovim starts, and where it is loaded from.

To help with this Neovim keeps track of which folders contained files that were sourced, which can be accessed with the following command:

:lua vim.print(vim.api.nvim_list_runtime_paths())