diff options
author | Ian Chamberlain <ian-h-chamberlain@users.noreply.github.com> | 2025-03-11 09:45:01 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-03-11 14:45:01 +0100 |
commit | 8b5a0a00c8cfe776c4227862c3fb32a07d154663 (patch) | |
tree | 447d3f2bed0bb30786c7faef373f7f40ab08613b /runtime/lua/vim | |
parent | 0829e7575d63d51f0e33df81be2a45099aedea97 (diff) | |
download | rneovim-8b5a0a00c8cfe776c4227862c3fb32a07d154663.tar.gz rneovim-8b5a0a00c8cfe776c4227862c3fb32a07d154663.tar.bz2 rneovim-8b5a0a00c8cfe776c4227862c3fb32a07d154663.zip |
feat(treesitter): allow disabling captures and patterns on TSQuery (#32790)
Problem: Cannot disable individual captures and patterns in treesitter queries.
Solution:
* Expose the corresponding tree-sitter API functions for `TSQuery` object.
* Add documentation for `TSQuery`.
* Return the pattern ID from `get_captures_at_pos()` (and hence `:Inspect!`).
Diffstat (limited to 'runtime/lua/vim')
-rw-r--r-- | runtime/lua/vim/treesitter.lua | 14 | ||||
-rw-r--r-- | runtime/lua/vim/treesitter/_meta/misc.lua | 3 | ||||
-rw-r--r-- | runtime/lua/vim/treesitter/_meta/tsquery.lua | 45 | ||||
-rw-r--r-- | runtime/lua/vim/treesitter/query.lua | 4 |
4 files changed, 56 insertions, 10 deletions
diff --git a/runtime/lua/vim/treesitter.lua b/runtime/lua/vim/treesitter.lua index a5362202fb..c2df96d9b4 100644 --- a/runtime/lua/vim/treesitter.lua +++ b/runtime/lua/vim/treesitter.lua @@ -288,15 +288,19 @@ function M.get_captures_at_pos(bufnr, row, col) local iter = q:query():iter_captures(root, buf_highlighter.bufnr, row, row + 1) - for id, node, metadata in iter do + for id, node, metadata, match in iter do if M.is_in_node_range(node, row, col) then ---@diagnostic disable-next-line: invisible local capture = q._query.captures[id] -- name of the capture in the query if capture ~= nil then - table.insert( - matches, - { capture = capture, metadata = metadata, lang = tree:lang(), id = id } - ) + local _, pattern_id = match:info() + table.insert(matches, { + capture = capture, + metadata = metadata, + lang = tree:lang(), + id = id, + pattern_id = pattern_id, + }) end end end diff --git a/runtime/lua/vim/treesitter/_meta/misc.lua b/runtime/lua/vim/treesitter/_meta/misc.lua index 99267bb36e..07a1c921c7 100644 --- a/runtime/lua/vim/treesitter/_meta/misc.lua +++ b/runtime/lua/vim/treesitter/_meta/misc.lua @@ -14,9 +14,6 @@ error('Cannot require a meta file') ---@field _set_logger fun(self: TSParser, lex: boolean, parse: boolean, cb: TSLoggerCallback) ---@field _logger fun(self: TSParser): TSLoggerCallback ----@class TSQuery: userdata ----@field inspect fun(self: TSQuery): TSQueryInfo - ---@class (exact) TSQueryInfo ---@field captures string[] ---@field patterns table<integer, (integer|string)[][]> diff --git a/runtime/lua/vim/treesitter/_meta/tsquery.lua b/runtime/lua/vim/treesitter/_meta/tsquery.lua new file mode 100644 index 0000000000..14b1fc3059 --- /dev/null +++ b/runtime/lua/vim/treesitter/_meta/tsquery.lua @@ -0,0 +1,45 @@ +---@meta +-- luacheck: no unused args +error('Cannot require a meta file') + +-- This could be documented as a module @brief like tsnode/tstree, but without +-- its own section header documenting it as a class ensures it still gets a helptag. + +--- Reference to an object held by the treesitter library that is used as a +--- component of the |vim.treesitter.Query| for language feature support. +--- See |treesitter-query| for more about queries or |vim.treesitter.query.parse()| +--- for an example of how to obtain a query object. +--- +---@class TSQuery: userdata +local TSQuery = {} -- luacheck: no unused + +--- Get information about the query's patterns and captures. +---@nodoc +---@return TSQueryInfo +function TSQuery:inspect() end + +--- Disable a specific capture in this query; once disabled the capture cannot be re-enabled. +--- {capture_name} should not include a leading "@". +--- +--- Example: To disable the `@variable.parameter` capture from the vimdoc highlights query: +--- ```lua +--- local query = vim.treesitter.query.get('vimdoc', 'highlights') +--- query.query:disable_capture("variable.parameter") +--- vim.treesitter.get_parser():parse() +--- ``` +---@param capture_name string +function TSQuery:disable_capture(capture_name) end + +--- Disable a specific pattern in this query; once disabled the pattern cannot be re-enabled. +--- The {pattern_index} for a particular match can be obtained with |:Inspect!|, or by reading +--- the source of the query (i.e. from |vim.treesitter.query.get_files()|). +--- +--- Example: To disable `|` links in vimdoc but keep other `@markup.link`s highlighted: +--- ```lua +--- local link_pattern = 9 -- from :Inspect! +--- local query = vim.treesitter.query.get('vimdoc', 'highlights') +--- query.query:disable_pattern(link_pattern) +--- local tree = vim.treesitter.get_parser():parse()[1] +--- ``` +---@param pattern_index integer +function TSQuery:disable_pattern(pattern_index) end diff --git a/runtime/lua/vim/treesitter/query.lua b/runtime/lua/vim/treesitter/query.lua index 17088ac0eb..5830cc12e0 100644 --- a/runtime/lua/vim/treesitter/query.lua +++ b/runtime/lua/vim/treesitter/query.lua @@ -10,7 +10,6 @@ local EXTENDS_FORMAT = '^;+%s*extends%s*$' local M = {} ----@nodoc ---Parsed query, see |vim.treesitter.query.parse()| --- ---@class vim.treesitter.Query @@ -344,9 +343,10 @@ api.nvim_create_autocmd('OptionSet', { --- Parses a {query} string and returns a `Query` object (|lua-treesitter-query|), which can be used --- to search the tree for the query patterns (via |Query:iter_captures()|, |Query:iter_matches()|), ---- or inspect the query via these fields: +--- or inspect/modify the query via these fields: --- - `captures`: a list of unique capture names defined in the query (alias: `info.captures`). --- - `info.patterns`: information about predicates. +--- - `query`: the underlying |TSQuery| which can be used to disable patterns or captures. --- --- Example: --- ```lua |