nvim-treesitter-textobjects icon indicating copy to clipboard operation
nvim-treesitter-textobjects copied to clipboard

Autoreload cached mappings on query save

Open lf- opened this issue 5 months ago • 2 comments

Is your feature request related to a problem? Please describe.

I want to be able to :TSEditQuery to edit a query and then save it and then have it work.

Currently this is jacked because treesitter-textobjects caches queryable objects in the key map:

:lua pp(require('nvim-treesitter.textobjects.select').keymaps_per_buf[62])
{ {
    lhs = "aa",
    mode = "o"
  }, {
    lhs = "aa",
    mode = "x"
  }, {
    lhs = "if",
    mode = "o"
  }, {
    lhs = "if",
    mode = "x"
  } }

https://github.com/nvim-treesitter/nvim-treesitter-textobjects/blob/89ebe73cd2836db80a22d9748999ace0241917a5/lua/nvim-treesitter/textobjects/select.lua#L152-L154

Describe the solution you'd like The keymaps should be detached and reattached on query save IMO.

Describe alternatives you've considered You can restart vim I guess, that is no fun.

Additional context Add any other context or screenshots about the feature request here.

lf- avatar Jul 24 '25 20:07 lf-

More debugging reveals that this is a cause:

https://github.com/nvim-treesitter/nvim-treesitter-textobjects/blob/89ebe73cd2836db80a22d9748999ace0241917a5/lua/nvim-treesitter/textobjects/shared.lua#L96-L110

... which is because treesitter.get_query returns the wrong captures. WHAT.

{
  _processed_patterns = { {
      directives = { <1>{ "make-range!", "parameter.outer", 1, 3 } },
      predicates = {}
    } },
  captures = <2>{ "_start", "wat", "function.inner", "parameter.outer" },
  info = {
    captures = <table 2>,
    patterns = { { <table 1> } }
  },
  lang = "starlark",
  query = <userdata 1>,
  <metatable> = <3>{
    __index = <table 3>,
    _apply_directives = <function 1>,
    _match_predicates = <function 2>,
    _process_patterns = <function 3>,
    iter_captures = <function 4>,
    iter_matches = <function 5>,
    new = <function 6>
  }
}

lf- avatar Jul 24 '25 20:07 lf-

At least part of this is https://github.com/neovim/neovim/issues/35056.

Full workaround I am committing in my neovim config:

local ts_configs = require('nvim-treesitter.configs')

local function reload_ts_module(mod)
    local config_mod = ts_configs.get_module(mod)
    if not config_mod then
        return
    end

    local bufs = config_mod.enabled_buffers or vim.api.nvim_list_bufs()

    for _, bufnr in pairs(bufs) do
        if ts_configs.is_enabled(mod, nil, bufnr) then
            ts_configs.detach_module(mod, bufnr)
            ts_configs.attach_module(mod, bufnr)
        end
    end
end


augroup('reload queries on query save', function(autocmd) -- https://github.com/nvim-treesitter/nvim-treesitter-textobjects/issues/787
    autocmd(
        'BufWritePost',
        {
            pattern = '*.scm',
            callback = function ()
                -- private API: https://github.com/neovim/neovim/issues/35056
                ---@diagnostic disable-next-line: undefined-field
                vim.treesitter.query.get:clear()
                reload_ts_module( "textobjects.move")
                reload_ts_module("textobjects.select")
                reload_ts_module("textobjects.lsp_interop")
                reload_ts_module("textobjects.swap")
            end
        }
    )
end)

lf- avatar Jul 24 '25 21:07 lf-