3. Vim’s ftplugin
system
This is part three in a seven-part series explaining how to use the Vim or Neovim text editors to efficiently write LaTeX documents.
This article covers Vim’s ftplugin
system, which allows you to create customizations that apply only to LaTeX files (or any other file type).
Understanding this article will give you a clearer mental model of how the VimTeX plugin works.
Contents of this article
The basics of file-specific Vim plugins
What is a plugin?
Officially, as defined in :help plugin
, a plugin is the name for a Vimscript file that is loaded when you start Vim.
If you have ever created a vimrc
or init.vim
file, which are just simple Vimscript files, you have technically written a Vim plugin.
Just like your vimrc
, a plugin’s purpose is to extend Vim’s default functionality to meet your personal needs.
A package, as defined in :help packages
, is a set of Vimscript files.
To be pedantic, what most people (myself included) refer to in everyday usage as a Vim plugin is technically a package.
That’s irrelevant; the point is that plugins and packages are just Vimscript files used to extend Vim’s default functionality, and, if you have ever written a vimrc
or init.vim
, it is within your means to write more advanced plugins, too.
Runtimepath: where Vim looks for files to load
Vim’s runtimepath
is a list of directories, both in your home directory and system-wide, that Vim searches for files to load at runtime, i.e. when opening Vim.
Below is a list of some directories on Vim’s default runtimepath
, taken from :help runtimepath
—you will probably recognize some of them from your own Vim setup.
Directory or File | Description |
---|---|
filetype.vim |
Used to set a file’s Vim filetype |
autoload/ |
Scripts loaded dynamically using Vim’s autoload feature |
colors/ |
Vim colorscheme files conventionally go here |
compiler/ |
Contains files related to compilation and make functionality |
doc/ |
Contains documentation and help files |
ftplugin/ |
Filetype-specific configurations go here |
indent/ |
Contains scripts related to indentation |
pack/ |
Vim’s default location for third-party plugins |
spell/ |
Files related to spell-checking |
syntax/ |
Contains scripts related to syntax highlighting |
You can view your current runtimepath
with :echo &runtimepath
.
If you want a plugin to load automatically when you open Vim, you must place the plugin in an appropriate location in your runtimepath
.
For the purposes of this series, the most important directory in your runtimepath
is the ftplugin/
directory in your Vim config folder, i.e. the directory ~/.vim/ftplugin/
on Vim and ~/.config/nvim/ftplugin/
on Neovim.
Here’s why it is so important: ftplugin/
is the correct directory to place LaTeX-specific configuration (or in general any configuration that you wish to apply only to a single file type), and this entire series is all about LaTeX-specific configuration.
Vim’s filetype plugin system
Say you’ve written some customizations that you want to apply only to LaTeX files, and not to any other file types. To keep your LaTeX customizations specific to only LaTeX files, you should use Vim’s filetype plugin system.
Filetype plugin basic recipe
Say you want to write a plugin that applies only to LaTeX files. Here’s what to do:
-
Add the following lines to your
vimrc
(these settings are enabled by default on Neovim—see:help nvim-defaults
—but it can’t hurt to place them in yourinit.vim
, too):filetype on " enable filetype detection filetype plugin on " load file-specific plugins filetype indent on " load file-specific indentation
These lines enable filetype detection and filetype-specific plugins and indentation. To get an overview of your current filetype status, use the
:filetype
command; you want an output that reads:" With Vim's filetype-specific functionality enabled, the output looks like this filetype detection:ON plugin:ON indent:ON
See
:help filetype
for more information on filetype plugins. -
Create the file structure
~/.vim/ftplugin/tex.vim
. Your LaTeX-specific mappings and functions will go in~/.vim/ftplugin/tex.vim
. That’s it! Assuming you followed step 1, anything intex.vim
will be loaded only when editing files with thetex
filetype (i.e. LaTeX and related files), and will not interfere with your other filetype plugins.Optional tip: You can also split up your
tex
customizations among multiple files (instead of having a single, clutteredtex.vim
file). To do this, create the file structure~/.vim/ftplugin/tex/*.vim
. Any Vimscript files inside~/.vim/ftplugin/tex/
will then load automatically when editing files with thetex
filetype. As a concrete example, you might design yourftplugin
directory like this:# Two ways to have LaTeX-specific configuration; # note the dedicated `tex` folder in the second example ftplugin/ ftplugin/ ├── tex.vim ├── markdown.vim ├── markdown.vim ├── python.vim └── python.vim └── tex ├── vimtex.vim └── main.vim
The first example uses a single
tex.vim
file insideftplugin
. In the second example, thetex
-specific configuration is divided into two files—vimtex.vim
might store configuration related to the VimTeX plugin andmain.tex
would store general settings for thetex
filetype.
The following sections explain how loading filetype plugins works under the hood.
Automatic filetype detection
-
Vim keeps track of a file’s type using the
filetype
option. You can view Vim’s opinion of a file’sfiletype
using the commands:set filetype?
or:echo &filetype
. -
Once you set
:filetype on
in yourvimrc
(enabled by default on Neovim), Vim automatically detects common filetypes (LaTeX included) based on the file’s extension using a Vimscript file calledfiletype.vim
that ships with Vim. You can viewfiletype.vim
’s source code at the path$VIMRUNTIME/filetype.vim
(first use:echo $VIMRUNTIME
in Vim to determine$VIMRUNTIME
).
Manual filetype detection
If Vim’s default filetype detection using filetype.vim
fails (this only happens for exotic filetypes), you can also manually configure Vim to detect the target filetype.
Note that manual detection of exotic filetypes is not needed for this tutorial (Vim detects LaTeX files without any configuration on your part), so feel free to skip ahead.
But if you’re curious, here’s an example using LilyPond files, which by convention have the extension .ly
.
(LilyPond is a free and open-source text-based system for elegantly typesetting musical notation; as an analogy, LilyPond is for music what LaTeX is for math.)
Here’s what to do for manual filetype detection:
-
Identify the extension(s) you expect for the target filetype, e.g.
.ly
for LilyPond. -
Make up some reasonable value that Vim’s
filetype
variable should take for the target filetype. This can match the extension, but doesn’t have to. For LilyPond files I usefiletype=lilypond
. -
Create the file
~/.vim/ftdetect/lilypond.vim
(the file name, in this caselilypond.vim
, can technically be anything ending in.vim
, but by convention should match the value offiletype
). Inside the file add the single lineautocmd BufNewFile,BufRead *.ly set filetype=lilypond
Of course replace
.ly
with your target extension andlilypond
with the value offiletype
you chose in step 2.
How Vim loads filetype plugins
The relevant documentation lives at :help filetype
and :help ftplugin
, but is rather long.
For our purposes:
-
When you open a file with Vim, assuming you have set
:filetype on
, Vim tries to determine the file’s type by cross-checking the file’s extension against a set of extensions found in$VIMRUNTIME/filetype.vim
. Generally this method works out of the box (filetype.vim
is over 2300 lines and covers the majority of common files).If the file’s type is not detected from extension, Vim attempts to guess the file type based on file contents using
$VIMRUNTIME/scripts.vim
(reference::help filetype
). If both$VIMRUNTIME/filetype.vim
and$VIMRUNTIME/scripts.vim
fail, Vim checks the contents offtdetect
directories in yourruntimepath
, as described in the section Manual filetype detection a few paragraphs above. -
If Vim successfully detects a file’s type, it sets the value of the
filetype
option to indicate the file type. Often, but not always, the value offiletype
matches the file’s conventional extension; for LaTeX this value isfiletype=tex
. You can check the current value offiletype
withecho &filetype
or:set filetype?
. -
After the
filetype
option is set, Vim checks the contents of your~/.vim/ftplugin
directory, if you have one. If Vim finds either…-
a file
ftplugin/{filetype}.vim
(e.g.filetype/tex.vim
forfiletype=tex
), then Vim loads the contents of{filetype}.vim
, or -
a directory
ftplugin/{filetype}
(e.g.ftplugin/tex
for thefiletype=tex
), then Vim loads all.vim
files inside the{filetype}
directory.
-
As a best practice, keep filetype-specific settings in either in a dedicated {filetype}.vim
file at ftplugin/{filetype}.vim
,
or split up among multiple files in ftplugin/{filetype}/*.vim
.
Think of the ftplugin
files as a vimrc
for one file type only,
and keep your actual vimrc
for global settings you want to apply to all file types.
The original writing, images, and animations in this series are licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.