- Published on
How to setup vimtex for LazyVim
What is Vimtex?
Vimtex is a vim plugin that provides support for writing latex in vim. It can also be used in neovim.
I use the LazyVim distro to base my setups on. Below are the plugins I use for my latex compilation.
Latex Compiler
I use latexmk
to compile my documents. Below is my current working configuration of the global .latexmkrc
file. I use lualatex
because it is the most modern and has the best support for unicode and modern fonts.
.latexmkrc
$pdf_mode = 4; ## sets lualatex to default engine.
$dvi_mode = 0;
$postscript_mode = 0;
Vimtex
~/.config/nvim/lua/plugins/vimtex.lua
return {
"lervag/vimtex",
lazy = false, -- lazy-loading will disable inverse search
config = function()
vim.api.nvim_create_autocmd({ "FileType" }, {
group = vim.api.nvim_create_augroup("lazyvim_vimtex_conceal", { clear = true }),
pattern = { "bib", "tex" },
callback = function()
vim.wo.conceallevel = 0
end,
})
vim.g.vimtex_mappings_disable = { ["n"] = { "K" } } -- disable `K` as it conflicts with LSP hover
vim.g.vimtex_quickfix_method = vim.fn.executable("pplatex") == 1 and "pplatex" or "latexlog"
vim.g.vimtex_view_method = "skim" -- <== macos specific, you can use zathura or sumatra or something else.
vim.g.vimtex_view_skim_sync = 1
vim.g.vimtex_view_skim_activate = 1
vim.g.vimtex_view_skim_reading_bar = 1
vim.g.vimtex_compiler_latexmk = {
aux_dir = "./aux",
out_dir = "./out",
}
end,
}
Using this configuration, you can use \l
keystroke to bring up the vimtex menu. It supports real-time compilation, meaning that the pdf viewer is automatically updated. I have it set such that it uses skim
for the pdf viewer, which is specific to OsX, but you can change it to something else. The auxiliary files and final outputs are saved under aux
and out
of relative to the .tex
file.
Synctex with Vimtex
Syntax is basically a utility for latex that allows you to jump from the pdf to the corresponding line in the .tex
file. If you have used overleaf, you have probably used this feature already. Vimtex has a nice support for SyncTex, which can be specified
Indentation
~/.config/nvim/lua/plugins/conform.lua
return {
"stevearc/conform.nvim",
optional = true,
opts = {
format = {
timeout_ms = 3000,
async = false, -- not recommended to change
quiet = false, -- not recommended to change
},
formatters_by_ft = {
["tex"] = { "latexindent" },
-- can add more here for different languages
},
},
}
Synatx Highlighting
~/.config/nvim/lua/plugins/treesitter.lua
return {
"nvim-treesitter/nvim-treesitter",
opts = function(_, opts)
vim.treesitter.language.register("markdown", "mdx")
-- vim.list_extend(opts.highlight.disable, { "tsx" })
if type(opts.ensure_installed) == "table" then
vim.list_extend(opts.ensure_installed, {
"bibtex",
"latex",
-- you can add more here
})
end
if type(opts.highlight.disable) == "table" then
vim.list_extend(opts.highlight.disable, { "latex", "bibtex" })
else
opts.highlight.disable = { "latex", "bibtex" }
end
end,
}
Snippets
Custom snippets is one of the most powerful tools you can leverage when writing your latex with vim and vimtex. LuaSnip is the plugin that manages all types of snippets
~/config/nvim/lua/plugins/luasnip.lua
return {
"L3MON4D3/LuaSnip",
dependencies = {
"rafamadriz/friendly-snippets",
},
opts = {
history = true,
delete_check_events = "TextChanged",
},
config = function()
local luasnip_loader = require("luasnip.loaders.from_vscode")
luasnip_loader.lazy_load({ paths = { "./snippets" }})
luasnip_loader.lazy_load()
end,
}
The config function here ensures that my custom snippets appear first, so that I can override default snippets for common stuff like figure
or table
.
Note that I am using the relative path. Since everything under lua
is loaded by nvim, this ends up pointing to ~/config/nvim/snippets
.
Inside that directory, you can create a snippets file that uses vscode style snippets. In order to do this, you need to have a package.json
file at the root of the snippets directory. You can also use subdirectories to maintain snippets for different purposes.
~/config/nvim/snippets/package.json
{
"name": "custom-snippets",
"contributes": {
"snippets": [
{
"language": [
"tex"
],
"path": "./latex/tex-snippets.json"
}
]
}
}
Again, note the use of relative paths. The relative path here starts from the directory that package.json
is placed in.
~/config/nvim/snippets/latex/tex-snippets.json
{
"Minipage": {
"prefix": "minipage",
"body": ["\\begin{minipage}[t]{$0\\textwidth}", "\\end{minipage}%"],
"description": "Add a table"
},
"Frame": {
"prefix": "frame",
"body": ["\\begin{frame}", "\t\\frametitle{$1}", "\\end{frame}", "$0"],
"description": "Add a beamer frame"
},
}