return { -- Treesitter is a new parser generator tool that we can -- use in Neovim to power faster and more accurate -- syntax highlighting. { "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 vim.cmd.TSUpdate() 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" }, opts = { 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 plugin LazyPlugin ---@param opts TSConfig config = function(plugin, opts) if vim.fn.executable("tree-sitter") == 0 then LazyVim.error({ "**treesitter-main** requires the `tree-sitter` CLI executable to be installed.", "Run `:checkhealth nvim-treesitter` for more information.", }) return end if type(opts.ensure_installed) ~= "table" then LazyVim.error("`nvim-treesitter` opts.ensure_installed must be a table") end local TS = require("nvim-treesitter") if not TS.get_installed then LazyVim.error("Please use `:Lazy` and update `nvim-treesitter`") return end TS.setup(opts) local needed = LazyVim.dedup(opts.ensure_installed --[[@as string[] ]]) LazyVim.ui.installed = TS.get_installed("parsers") local install = vim.tbl_filter(function(lang) return not LazyVim.ui.have(lang) end, needed) if #install > 0 then TS.install(install, { summary = true }):await(function() LazyVim.ui.installed = TS.get_installed("parsers") end) end vim.api.nvim_create_autocmd("FileType", { callback = function(ev) if LazyVim.ui.have(ev.match) then pcall(vim.treesitter.start) end end, }) end, }, { "nvim-treesitter/nvim-treesitter-textobjects", branch = "main", event = "VeryLazy", opts = {}, keys = function() local moves = { 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" }, } local ret = {} ---@type LazyKeysSpec[] 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") ret[#ret + 1] = { key, function() -- don't use treesitter if in diff mode and the key is one of the c/C keys if vim.wo.diff and key:find("[cC]") then return vim.cmd("normal! " .. key) end require("nvim-treesitter-textobjects.move")[method](query, "textobjects") end, desc = desc, mode = { "n", "x", "o" }, silent = true, } end end return ret end, 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) end, }, -- Automatically add closing tags for HTML and JSX { "windwp/nvim-ts-autotag", event = "LazyFile", opts = {}, }, }