-- Whenever upgrading the plugin, also run :TSUpdate to upgrade all parsers vim.api.nvim_create_autocmd("PackChanged", { callback = function(e) if e.data.spec.name ~= "nvim-treesitter" then return end if e.data.kind == "install" or e.data.kind == "update" then vim.notify("nvim-treesitter updated, running TSUpdate...", vim.log.levels.INFO) require("nvim-treesitter").update() vim.notify("nvim-treesitter update completed successfully!", vim.log.levels.INFO) end end, }) -- Language parser tool to power faster and more accurate syntax highlighting vim.pack.add { { src = "https://github.com/nvim-treesitter/nvim-treesitter", version = "main" } } vim.pack.add { { src = "https://github.com/nvim-treesitter/nvim-treesitter-textobjects", version = "main" }, } require("nvim-treesitter").setup { auto_install = true, ensure_installed = { "bash", "c", "css", "diff", "dockerfile", "git_config", "git_rebase", "gitcommit", "gitignore", "go", "html", "html", "hyprlang", "javascript", "jsdoc", "json", "jsonc", "kdl", "lua", "lua", "luadoc", "markdown", "markdown_inline", "python", "rust", "scss", "toml", "typescript", "vim", "vimdoc", "yaml", }, indent = { enable = true }, highlight = { enable = true, additional_vim_regex_highlighting = false, }, incremental_selection = { enable = true, keymaps = { init_selection = "gnn", node_incremental = "grn", scope_incremental = "grc", node_decremental = "grm", }, }, } require("nvim-treesitter-textobjects").setup { select = { enable = true, lookahead = true, }, move = { enable = true, set_jumps = true, }, swap = { enable = true, -- swap_next = { -- ["a"] = "@parameter.inner", -- }, -- swap_previous = { -- ["A"] = "@parameter.inner", -- }, }, lsp_interop = { enable = true, }, } local function map_object(modes, fn, bind, object, desc) vim.keymap.set(modes, bind, function() fn(object) end, { desc = desc }) end local select = require("nvim-treesitter-textobjects.select") local move = require("nvim-treesitter-textobjects.move") local swap = require("nvim-treesitter-textobjects.swap") local function register_select(bind, object, desc) map_object( { "x", "o" }, function(obj) select.select_textobject(obj, "textobjects") end, bind, object, desc ) end local function register_move(fn, bind, object, desc) map_object({ "n", "x", "o" }, fn, bind, object, desc) end register_select("af", "@function.outer", "Function") register_select("if", "@function.inner", "Function") register_select("ac", "@class.outer", "Class") register_select("ic", "@class.inner", "Class") register_select("ao", "@condition.outer", "Condition") register_select("io", "@condition.inner", "Condition") register_select("al", "@loop.outer", "Loop") register_select("il", "@loop.inner", "Loop") register_select("aa", "@parameter.outer", "Parameter") register_select("ia", "@parameter.inner", "Parameter") register_select("ab", "@block.outer", "Block") register_select("ib", "@block.inner", "Block") register_select("a/", "@comment.outer", "Comment") register_select("i/", "@comment.inner", "Comment") register_move(move.goto_next_start, "]f", "@function.outer", "Function") register_move(move.goto_next_start, "]c", "@class.outer", "Class") register_move(move.goto_next_start, "]l", "@loop.outer", "Loop") register_move(move.goto_next_start, "]a", "@parameter.inner", "Parameter") register_move(move.goto_next_start, "]b", "@block.outer", "Block") register_move(move.goto_next_start, "]/", "@comment.outer", "Comment") register_move(move.goto_next_end, "]F", "@function.outer", "End of function") register_move(move.goto_next_end, "]C", "@class.outer", "End of class") register_move(move.goto_next_end, "]L", "@loop.outer", "End of loop") register_move(move.goto_next_end, "]A", "@parameter.inner", "End of parameter") register_move(move.goto_next_end, "]B", "@block.outer", "End of block") register_move(move.goto_next_end, "]?", "@comment.outer", "End of comment") register_move(move.goto_previous_start, "[f", "@function.outer", "Function") register_move(move.goto_previous_start, "[c", "@class.outer", "Class") register_move(move.goto_previous_start, "[l", "@loop.outer", "Loop") register_move(move.goto_previous_start, "[a", "@parameter.inner", "Parameter") register_move(move.goto_previous_start, "[b", "@block.outer", "Block") register_move(move.goto_previous_start, "[/", "@comment.outer", "Comment") register_move(move.goto_previous_end, "[F", "@function.outer", "End of function") register_move(move.goto_previous_end, "[C", "@class.outer", "End of class") register_move(move.goto_previous_end, "[L", "@loop.outer", "End of loop") register_move(move.goto_previous_end, "[A", "@parameter.inner", "End of parameter") register_move(move.goto_previous_end, "[B", "@block.outer", "End of block") register_move(move.goto_previous_end, "[?", "@comment.outer", "End of comment") -- vim.keymap.set( -- "n", -- "a", -- function() swap.swap_next("@parameter.inner") end, -- { desc = "swap next parameter" } -- ) -- vim.keymap.set( -- "n", -- "A", -- function() swap.swap_previous("@parameter.outer") end, -- { desc = "swap previous parameter" } -- ) local ts_repeat_move = require("nvim-treesitter-textobjects.repeatable_move") -- Repeat movement with ; and , -- ensure ; goes forward and , goes backward regardless of the last direction vim.keymap.set({ "n", "x", "o" }, ";", ts_repeat_move.repeat_last_move_next) vim.keymap.set({ "n", "x", "o" }, ",", ts_repeat_move.repeat_last_move_previous) -- Optionally, make builtin f, F, t, T also repeatable with ; and , vim.keymap.set({ "n", "x", "o" }, "f", ts_repeat_move.builtin_f_expr, { expr = true }) vim.keymap.set({ "n", "x", "o" }, "F", ts_repeat_move.builtin_F_expr, { expr = true }) vim.keymap.set({ "n", "x", "o" }, "t", ts_repeat_move.builtin_t_expr, { expr = true }) vim.keymap.set({ "n", "x", "o" }, "T", ts_repeat_move.builtin_T_expr, { expr = true }) -- Start treesitter vim.api.nvim_create_autocmd("FileType", { pattern = "*", callback = function(args) local lang = vim.treesitter.language.get_lang(args.match) if not lang then return end local ok = pcall(vim.treesitter.start, args.buf, lang) if not ok then -- no highlights.scm or parser → silently skip return end end, })