return { { "nvim-treesitter/nvim-treesitter", -- Load on these events for a snappier startup event = { "BufReadPost", "BufNewFile" }, -- Keep the build command to update parsers automatically build = ":TSUpdate", config = function() local configs = require("nvim-treesitter.configs") configs.setup({ -- Automatically install missing parsers ensure_installed = { "bash", "c", "comment", "css", "diff", "dockerfile", "git_config", "gitcommit", "gitignore", "go", "html", "http", "java", "javascript", "jsdoc", "json", "json5", "kotlin", "lua", "luadoc", "luap", "make", "markdown", "markdown_inline", "python", "query", "regex", "rst", "sql", "ssh_config", "svelte", "terraform", "toml", "tsx", "typescript", "typst", "vim", "vimdoc", "yaml", "groovy" }, -- Enable syntax highlighting highlight = { enable = true, -- Setting this to true will run `:h syntax` and Tree-sitter at the same time. -- Set to `false` if you want Treesitter to handle everything. additional_vim_regex_highlighting = false, }, -- Enable indentation based on treesitter indent = { enable = true }, }) -- Register custom filetypes for Treesitter vim.treesitter.language.register("groovy", "Jenkinsfile") -- Treesitter-based folding vim.opt.foldmethod = "expr" vim.opt.foldexpr = "v:lua.vim.treesitter.foldexpr()" vim.opt.foldlevel = 99 -- Prevents files from being folded by default end, }, { "nvim-treesitter/nvim-treesitter-context", dependencies = { "nvim-treesitter/nvim-treesitter" }, -- Context is only useful once you're actually inside a buffer event = "BufReadPost", opts = { enable = true, max_lines = 0, min_window_height = 0, line_numbers = true, multiline_threshold = 10, trim_scope = "outer", mode = "cursor", zindex = 20, }, config = function(_, opts) -- If the window is small, limit context to 1 line to save screen real estate if vim.api.nvim_win_get_height(0) < 50 then opts.multiline_threshold = 1 end require("treesitter-context").setup(opts) end, }, { "nvim-treesitter/nvim-treesitter-textobjects", lazy = true, config = function() require("nvim-treesitter.configs").setup({ textobjects = { select = { enable = true, lookahead = true, keymaps = { ["af"] = "@function.outer", ["if"] = "@function.inner", ["ac"] = "@class.outer", ["ic"] = "@class.inner", ["as"] = { query = "@local.scope", query_group = "locals" }, }, selection_modes = { ['@parameter.outer'] = 'v', ['@function.outer'] = 'V', ['@class.outer'] = '', }, }, move = { enable = true, set_jumps = true, goto_next_start = { ["]m"] = "@function.outer", ["]]"] = "@class.outer", ["]o"] = { query = { "@loop.inner", "@loop.outer" } }, ["]s"] = { query = "@local.scope", query_group = "locals" }, ["]z"] = { query = "@fold", query_group = "folds" }, }, goto_next_end = { ["]M"] = "@function.outer", ["]["] = "@class.outer", }, goto_previous_start = { ["[m"] = "@function.outer", ["[["] = "@class.outer", }, goto_previous_end = { ["[M"] = "@function.outer", ["[]"] = "@class.outer", }, }, swap = { enable = true, swap_next = { ["a"] = "@parameter.inner" }, swap_previous = { ["A"] = "@parameter.inner" }, }, }, }) -- Repeatable moves logic (keeps ; and , functionality) local ts_repeat_move = require("nvim-treesitter-textobjects.repeatable_move") 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) 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 }) end, } }