return { "nvim-treesitter/nvim-treesitter", branch = "main", build = ":TSUpdate", init = function() vim.o.foldmethod = "expr" vim.o.foldexpr = "v:lua.vim.treesitter.foldexpr()" end, config = function(_, opts) vim.api.nvim_create_autocmd('User', { pattern = 'TSUpdate', callback = function() vim.tbl_extend("force", require('nvim-treesitter.parsers'), opts.custom_parsers or {}) end }) local ts = require('nvim-treesitter') local already_installed = ts.get_installed() local parsers_to_install = vim.iter(opts.parsers or {}) :filter(function(parser) return not vim.tbl_contains(already_installed, parser) end) :totable() ts.install(parsers_to_install) -- Auto-install and start parsers for any buffer vim.api.nvim_create_autocmd({ "BufRead", "FileType" }, { desc = "Enable Treesitter", callback = function(event) local bufnr = event.buf local filetype = vim.api.nvim_get_option_value("filetype", { buf = bufnr }) -- Skip if no filetype if filetype == "" then return end -- Get parser name based on filetype local parser_name = vim.treesitter.language.get_lang(filetype) if not parser_name then vim.notify(vim.inspect("No treesitter parser found for filetype: " .. filetype), vim.log.levels.WARN) return end -- Try to get existing parser local parser_configs = require("nvim-treesitter.parsers") if not parser_configs[parser_name] then return -- Parser not available, skip silently end local parser_exists = pcall(vim.treesitter.get_parser, bufnr, parser_name) local function init_treesitter() -- vim.notify(vim.inspect("Starting treesitter parser " .. parser_name .. " for filetype: " .. filetype), vim.log.levels.WARN) vim.treesitter.start(bufnr, parser_name) -- Use regex based syntax-highlighting as fallback as some plugins might need it -- vim.bo[bufnr].syntax = "ON" -- vim.wo.foldtext = "v:lua.vim.treesitter.foldtext()" -- Use treesitter for indentation vim.bo[bufnr].indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()" end if not parser_exists then -- check if parser is already installed if vim.tbl_contains(already_installed, parser_name) then vim.notify("Parser for " .. parser_name .. " already installed.", vim.log.levels.INFO) init_treesitter() -- else -- -- If not installed, install parser synchronously -- vim.notify("Installing parser for " .. parser_name, vim.log.levels.INFO) -- treesitter.install({ parser_name }):await(init_treesitter) end else init_treesitter() end end, }) end, opts = { parsers = { "lua", "c", "vim", "vimdoc", "query", "rust", "fish", "json", "javascript", "latex", "markdown", "markdown_inline", "zig", "typescript", "toml", "svelte", "comment", "html", "typst", "ron", "smali", "java", "kotlin", "styled", "nix", "gitignore", "meson" -- "d2" }, custom_parsers = { d2 = { install_info = { url = 'https://github.com/ravsii/tree-sitter-d2', queries = 'queries', }, } } }, lazy = false }