-- Current nvim-treesitter main branch + nvim-treesitter-textobjects main branch. -- Requires Neovim >= 0.12, tree-sitter CLI, a C compiler, and both plugins. -- The old nvim-treesitter.configs module no longer exists on main. local ts = require('nvim-treesitter') local textobjects = require('nvim-treesitter-textobjects') -- Install parsers explicitly with :TSInstall or -- :lua require('nvim-treesitter').install({ 'lua', 'vim', 'c' }) -- Update installed parsers after plugin updates with :TSUpdate. -- Unlike the old API, there is no auto_install/sync_install option. -- Enable highlighting for buffers with installed parsers, except for large -- files. Core Neovim supplies highlighting; nvim-treesitter supplies parsers. local max_filesize = 100 * 1024 local group = vim.api.nvim_create_augroup('UserTreesitterHighlight', { clear = true }) vim.api.nvim_create_autocmd('FileType', { group = group, callback = function(args) local buf = args.buf local name = vim.api.nvim_buf_get_name(buf) if name ~= '' then local stat = vim.uv.fs_stat(name) if stat and stat.size > max_filesize then return end end -- Don't error for filetypes without an installed parser. pcall(vim.treesitter.start, buf) end, }) textobjects.setup({ select = { lookahead = true, selection_modes = { ['@parameter.outer'] = 'v', ['@function.outer'] = 'V', ['@function.inner'] = 'V', ['@block.inner'] = 'V', ['@block.outer'] = 'V', }, -- Corrected from the original pattern '^function', which could never -- match a capture name beginning with '@'. include_surrounding_whitespace = function(q) return q.query_string:match('%.inner$') == nil and q.query_string:match('^@function') ~= nil end, }, move = { set_jumps = true }, }) local select = require('nvim-treesitter-textobjects.select') local move = require('nvim-treesitter-textobjects.move') local selections = { am = '@function.outer', im = '@function.inner', af = '@function.outer', ['if'] = '@function.inner', aC = '@class.outer', iC = '@class.inner', aa = '@parameter.outer', ia = '@parameter.inner', iq = '@block.inner', aq = '@block.outer', ['a;'] = '@statement.outer', ['i;'] = '@statement.inner', } for lhs, query in pairs(selections) do vim.keymap.set({ 'x', 'o' }, lhs, function() select.select_textobject(query, 'textobjects') end, { desc = 'Tree-sitter select ' .. query }) end -- The original mapping references a custom capture; it only works when -- you provide a matching textobjects query for the current language. for lhs, query in pairs({ [']C'] = '@injectable_constructor.params.inner', [']c'] = '@class.outer', }) do vim.keymap.set({ 'n', 'x', 'o' }, lhs, function() move.goto_next_start(query, 'textobjects') end) end for lhs, query in pairs({ ['[C'] = '@injectable_constructor.params.inner', ['[c'] = '@class.outer', }) do vim.keymap.set({ 'n', 'x', 'o' }, lhs, function() move.goto_previous_start(query, 'textobjects') end) end