Yet another tree-sitter powered indent plugin for Neovim.
Yet another tree-sitter indent plugin for Neovim.
This plugin was originally created when the experience of builtin indent module of nvim-treesitter was still terrible. Now since it has improved a lot with better community support, this plugin should be no longer needed if the upstream one already satisfies you.
If you are still frustrated with the 'official' indent module or interested in this plugin, welcome to provide feedback or submit any issues. Take a glance at features to learn about the differences.
More languages could be supported by setup or adding config files to configs/ directory.
This plugin is always developed based on latest neovim and nvim-treesitter. Please consider upgrading them if there is any compatibility issue.
The plugin has been completely rewritten since legacy
tag. Use that if you prefer not migrating to the current version for some reason.
use({ "yioneko/nvim-yati", tag = "*", requires = "nvim-treesitter/nvim-treesitter" })
Plug "nvim-treesitter/nvim-treesitter"
Plug "yioneko/nvim-yati", { 'tag': '*' }
The module is required to be enabled to work:
require("nvim-treesitter.configs").setup {
yati = {
enable = true,
-- Disable by languages, see `Supported languages`
disable = { "python" },
-- Whether to enable lazy mode (recommend to enable this if bad indent happens frequently)
default_lazy = true,
-- Determine the fallback method used when we cannot calculate indent by tree-sitter
-- "auto": fallback to vim auto indent
-- "asis": use current indent as-is
-- "cindent": see `:h cindent()`
-- Or a custom function return the final indent result.
default_fallback = "auto"
},
indent = {
enable = false -- disable builtin indent module
}
}
I also created an accompanying regex-based indent plugin (vim-tmindent) to support saner fallback indent calculation, which could be a drop-in replacement of builtin indent method of vim. See integration for its fallback setup.
If you want to use the indent module simultaneously, disable the indent module for languages to be handled by this plugin.
require("nvim-treesitter.configs").setup {
indent = {
enable = true,
disable = { "html", "javascript" }
},
-- And optionally, disable the conflict warning emitted by plugin
yati = {
suppress_conflict_warning = true,
},
}
Example for a more customized setup:
local get_builtin = require("nvim-yati.config").get_builtin
-- This is just an example, not recommend to do this since the result is unpredictable
local js_overrides = vim.tbl_deep_extend("force", get_builtin("javascript"), {
lazy = false,
fallback = function() return -1 end,
nodes = {
["if_statement"] = { "scope" }, -- set attributes by node
},
handlers = {
on_initial = {},
on_travers = {
function(ctx) return false end, -- set custom handlers
}
}
})
require("nvim-treesitter.configs").setup {
yati = {
enable = true,
disable = { "python" },
default_lazy = false,
default_fallback = function() return -1 end, -- provide custom fallback indent method
overrides = {
javascript = js_overrides -- override config by language
}
}
}
More technical details goes there (highly unstable): CONFIG.md.
Fast, match node on demand by implementing completely in Lua, compared to executing scm query on the whole tree on every indent calculation.
Could be faster and more context aware if lazy
enabled, see default_lazy
option. This is specifically useful if the surrounding code doesn't obey indent rules:
function fun()
if abc then
if cbd then
a() -- new indent will goes here even if the parent node indent wrongly
end
end
end
Fallback indent method support to reuse calculated indent from tree.
Support indent in injection region. See sample.html for example.
Tests covered and handles much more edge cases. Refer samples in that directory for what the indentation would be like. The style is slightly opinionated as there is no actual standard, but customization is still possible.
Support for custom handlers to deal with complex scenarios. This plugin relies on dedicated handlers to fix many edge cases like the following one:
if True:
pass
else: # should auto dedent <-
# the parsed tree is broken here and cannot be handled by tree-sitter