TreeSitter
nvim-treesitter
Treesitter is a new parser generator tool that we can use in Neovim to power faster and more accurate syntax highlighting.
- Options
- Full Spec
opts = {
-- LazyVim config for treesitter
indent = { enable = true }, ---@type lazyvim.TSFeat
highlight = { enable = true }, ---@type lazyvim.TSFeat
folds = { enable = true }, ---@type lazyvim.TSFeat
ensure_installed = {
"bash",
"c",
"diff",
"html",
"javascript",
"jsdoc",
"json",
"jsonc",
"lua",
"luadoc",
"luap",
"markdown",
"markdown_inline",
"printf",
"python",
"query",
"regex",
"toml",
"tsx",
"typescript",
"vim",
"vimdoc",
"xml",
"yaml",
},
}
{
"nvim-treesitter/nvim-treesitter",
branch = "main",
version = false, -- last release is way too old and doesn't work on Windows
build = function()
local TS = require("nvim-treesitter")
if not TS.get_installed then
LazyVim.error("Please restart Neovim and run `:TSUpdate` to use the `nvim-treesitter` **main** branch.")
return
end
LazyVim.treesitter.ensure_treesitter_cli(function()
TS.update(nil, { summary = true })
end)
end,
lazy = vim.fn.argc(-1) == 0, -- load treesitter early when opening a file from the cmdline
event = { "LazyFile", "VeryLazy" },
cmd = { "TSUpdate", "TSInstall", "TSLog", "TSUninstall" },
opts_extend = { "ensure_installed" },
---@alias lazyvim.TSFeat { enable?: boolean, disable?: string[] }
---@class lazyvim.TSConfig: TSConfig
opts = {
-- LazyVim config for treesitter
indent = { enable = true }, ---@type lazyvim.TSFeat
highlight = { enable = true }, ---@type lazyvim.TSFeat
folds = { enable = true }, ---@type lazyvim.TSFeat
ensure_installed = {
"bash",
"c",
"diff",
"html",
"javascript",
"jsdoc",
"json",
"jsonc",
"lua",
"luadoc",
"luap",
"markdown",
"markdown_inline",
"printf",
"python",
"query",
"regex",
"toml",
"tsx",
"typescript",
"vim",
"vimdoc",
"xml",
"yaml",
},
},
---@param opts lazyvim.TSConfig
config = function(_, opts)
local TS = require("nvim-treesitter")
setmetatable(require("nvim-treesitter.install"), {
__newindex = function(_, k)
if k == "compilers" then
vim.schedule(function()
LazyVim.error({
"Setting custom compilers for `nvim-treesitter` is no longer supported.",
"",
"For more info, see:",
"- [compilers](https://docs.rs/cc/latest/cc/#compile-time-requirements)",
})
end)
end
end,
})
-- some quick sanity checks
if not TS.get_installed then
return LazyVim.error("Please use `:Lazy` and update `nvim-treesitter`")
elseif type(opts.ensure_installed) ~= "table" then
return LazyVim.error("`nvim-treesitter` opts.ensure_installed must be a table")
end
-- setup treesitter
TS.setup(opts)
LazyVim.treesitter.get_installed(true) -- initialize the installed langs
-- install missing parsers
local install = vim.tbl_filter(function(lang)
return not LazyVim.treesitter.have(lang)
end, opts.ensure_installed or {})
if #install > 0 then
LazyVim.treesitter.ensure_treesitter_cli(function()
TS.install(install, { summary = true }):await(function()
LazyVim.treesitter.get_installed(true) -- refresh the installed langs
end)
end)
end
vim.api.nvim_create_autocmd("FileType", {
group = vim.api.nvim_create_augroup("lazyvim_treesitter", { clear = true }),
callback = function(ev)
local ft, lang = ev.match, vim.treesitter.language.get_lang(ev.match)
if not LazyVim.treesitter.have(ft) then
return
end
---@param feat string
---@param query string
local function enabled(feat, query)
local f = opts[feat] or {} ---@type lazyvim.TSFeat
return f.enable ~= false
and not (type(f.disable) == "table" and vim.tbl_contains(f.disable, lang))
and LazyVim.treesitter.have(ft, query)
end
-- highlighting
if enabled("highlight", "highlights") then
pcall(vim.treesitter.start)
end
-- indents
if enabled("indent", "indents") then
LazyVim.set_default("indentexpr", "v:lua.LazyVim.treesitter.indentexpr()")
end
-- folds
if enabled("folds", "folds") then
if LazyVim.set_default("foldmethod", "expr") then
LazyVim.set_default("foldexpr", "v:lua.LazyVim.treesitter.foldexpr()")
end
end
end,
})
end,
}
nvim-treesitter-textobjects
- Options
- Full Spec
opts = {
move = {
enable = true,
set_jumps = true, -- whether to set jumps in the jumplist
-- LazyVim extention to create buffer-local keymaps
keys = {
goto_next_start = { ["]f"] = "@function.outer", ["]c"] = "@class.outer", ["]a"] = "@parameter.inner" },
goto_next_end = { ["]F"] = "@function.outer", ["]C"] = "@class.outer", ["]A"] = "@parameter.inner" },
goto_previous_start = { ["[f"] = "@function.outer", ["[c"] = "@class.outer", ["[a"] = "@parameter.inner" },
goto_previous_end = { ["[F"] = "@function.outer", ["[C"] = "@class.outer", ["[A"] = "@parameter.inner" },
},
},
}
{
"nvim-treesitter/nvim-treesitter-textobjects",
branch = "main",
event = "VeryLazy",
opts = {
move = {
enable = true,
set_jumps = true, -- whether to set jumps in the jumplist
-- LazyVim extention to create buffer-local keymaps
keys = {
goto_next_start = { ["]f"] = "@function.outer", ["]c"] = "@class.outer", ["]a"] = "@parameter.inner" },
goto_next_end = { ["]F"] = "@function.outer", ["]C"] = "@class.outer", ["]A"] = "@parameter.inner" },
goto_previous_start = { ["[f"] = "@function.outer", ["[c"] = "@class.outer", ["[a"] = "@parameter.inner" },
goto_previous_end = { ["[F"] = "@function.outer", ["[C"] = "@class.outer", ["[A"] = "@parameter.inner" },
},
},
},
config = function(_, opts)
local TS = require("nvim-treesitter-textobjects")
if not TS.setup then
LazyVim.error("Please use `:Lazy` and update `nvim-treesitter`")
return
end
TS.setup(opts)
vim.api.nvim_create_autocmd("FileType", {
group = vim.api.nvim_create_augroup("lazyvim_treesitter_textobjects", { clear = true }),
callback = function(ev)
if not (vim.tbl_get(opts, "move", "enable") and LazyVim.treesitter.have(ev.match, "textobjects")) then
return
end
---@type table<string, table<string, string>>
local moves = vim.tbl_get(opts, "move", "keys") or {}
for method, keymaps in pairs(moves) do
for key, query in pairs(keymaps) do
local desc = query:gsub("@", ""):gsub("%..*", "")
desc = desc:sub(1, 1):upper() .. desc:sub(2)
desc = (key:sub(1, 1) == "[" and "Prev " or "Next ") .. desc
desc = desc .. (key:sub(2, 2) == key:sub(2, 2):upper() and " End" or " Start")
if not (vim.wo.diff and key:find("[cC]")) then
vim.keymap.set({ "n", "x", "o" }, key, function()
require("nvim-treesitter-textobjects.move")[method](query, "textobjects")
end, {
buffer = ev.buf,
desc = desc,
silent = true,
})
end
end
end
end,
})
end,
}
nvim-ts-autotag
Automatically add closing tags for HTML and JSX
- Options
- Full Spec
opts = {}
{
"windwp/nvim-ts-autotag",
event = "LazyFile",
opts = {},
}