mirror of
https://github.com/neovim/neovim.git
synced 2025-12-11 00:52:44 +00:00
feat(treesitter): add ability to retreive a tree/node given a range
This commit is contained in:
@@ -549,6 +549,44 @@ function LanguageTree:contains(range)
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Gets the tree that contains {range}
|
||||||
|
---
|
||||||
|
---@param range table A text range
|
||||||
|
---@param opts table Options table
|
||||||
|
---@param opts.ignore_injections boolean (default true) Ignore injected languages.
|
||||||
|
function LanguageTree:tree_for_range(range, opts)
|
||||||
|
opts = opts or {}
|
||||||
|
local ignore = vim.F.if_nil(opts.ignore_injections, true)
|
||||||
|
|
||||||
|
if not ignore then
|
||||||
|
for _, child in pairs(self._children) do
|
||||||
|
for _, tree in pairs(child:trees()) do
|
||||||
|
if tree_contains(tree, range) then
|
||||||
|
return tree
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, tree in pairs(self._trees) do
|
||||||
|
if tree_contains(tree, range) then
|
||||||
|
return tree
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Gets the smallest named node that contains {range}
|
||||||
|
---
|
||||||
|
---@param range table A text range
|
||||||
|
---@param opts table Options table
|
||||||
|
---@param opts.ignore_injections boolean (default true) Ignore injected languages.
|
||||||
|
function LanguageTree:named_node_for_range(range, opts)
|
||||||
|
local tree = self:tree_for_range(range, opts)
|
||||||
|
return tree:root():named_descendant_for_range(unpack(range))
|
||||||
|
end
|
||||||
|
|
||||||
--- Gets the appropriate language that contains {range}
|
--- Gets the appropriate language that contains {range}
|
||||||
---
|
---
|
||||||
---@param range A text range, see |LanguageTree:contains|
|
---@param range A text range, see |LanguageTree:contains|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ local exec_lua = helpers.exec_lua
|
|||||||
local pcall_err = helpers.pcall_err
|
local pcall_err = helpers.pcall_err
|
||||||
local matches = helpers.matches
|
local matches = helpers.matches
|
||||||
local pending_c_parser = helpers.pending_c_parser
|
local pending_c_parser = helpers.pending_c_parser
|
||||||
|
local insert = helpers.insert
|
||||||
|
|
||||||
before_each(clear)
|
before_each(clear)
|
||||||
|
|
||||||
@@ -84,5 +85,33 @@ describe('treesitter language API', function()
|
|||||||
eq("Error executing lua: .../language.lua:0: no parser for 'borklang' language, see :help treesitter-parsers",
|
eq("Error executing lua: .../language.lua:0: no parser for 'borklang' language, see :help treesitter-parsers",
|
||||||
pcall_err(exec_lua, "new_parser = vim.treesitter.get_parser(0)"))
|
pcall_err(exec_lua, "new_parser = vim.treesitter.get_parser(0)"))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('retrieve the tree given a range', function ()
|
||||||
|
insert([[
|
||||||
|
int main() {
|
||||||
|
int x = 3;
|
||||||
|
}]])
|
||||||
|
|
||||||
|
exec_lua([[
|
||||||
|
langtree = vim.treesitter.get_parser(0, "c")
|
||||||
|
tree = langtree:tree_for_range({1, 3, 1, 3})
|
||||||
|
]])
|
||||||
|
|
||||||
|
eq('<node translation_unit>', exec_lua('return tostring(tree:root())'))
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('retrieve the node given a range', function ()
|
||||||
|
insert([[
|
||||||
|
int main() {
|
||||||
|
int x = 3;
|
||||||
|
}]])
|
||||||
|
|
||||||
|
exec_lua([[
|
||||||
|
langtree = vim.treesitter.get_parser(0, "c")
|
||||||
|
node = langtree:named_node_for_range({1, 3, 1, 3})
|
||||||
|
]])
|
||||||
|
|
||||||
|
eq('<node primitive_type>', exec_lua('return tostring(node)'))
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user