aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRiley Bruins <ribru17@hotmail.com>2024-07-28 13:23:40 -0700
committerChristian Clason <c.clason@uni-graz.at>2024-07-29 17:15:46 +0200
commitbd3b6ec8360e0dd6edfe74c3d0013fd2b98b989e (patch)
treef30673b516bd052b08ec38fb47dc715ef2e8406a
parent01a56a056cd5da89350583ef9fbc97fa29dcd8ef (diff)
downloadrneovim-bd3b6ec8360e0dd6edfe74c3d0013fd2b98b989e.tar.gz
rneovim-bd3b6ec8360e0dd6edfe74c3d0013fd2b98b989e.tar.bz2
rneovim-bd3b6ec8360e0dd6edfe74c3d0013fd2b98b989e.zip
feat(treesitter): add node_for_range function
This is identical to `named_node_for_range` except that it includes anonymous nodes. This maintains consistency in the API because we already have `descendant_for_range` and `named_descendant_for_range`.
-rw-r--r--runtime/doc/news.txt2
-rw-r--r--runtime/doc/treesitter.txt13
-rw-r--r--runtime/lua/vim/treesitter/languagetree.lua12
-rw-r--r--test/functional/treesitter/language_spec.lua11
4 files changed, 37 insertions, 1 deletions
diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt
index 2514ee8a92..2ddda72ae8 100644
--- a/runtime/doc/news.txt
+++ b/runtime/doc/news.txt
@@ -166,7 +166,7 @@ TERMINAL
TREESITTER
-• TODO
+• |LanguageTree:node_for_range()| gets anonymous and named nodes for a range
TUI
diff --git a/runtime/doc/treesitter.txt b/runtime/doc/treesitter.txt
index 2249f4865c..cd8a4d8ec5 100644
--- a/runtime/doc/treesitter.txt
+++ b/runtime/doc/treesitter.txt
@@ -1375,6 +1375,19 @@ LanguageTree:named_node_for_range({range}, {opts})
Return: ~
(`TSNode?`)
+ *LanguageTree:node_for_range()*
+LanguageTree:node_for_range({range}, {opts})
+ Gets the smallest node that contains {range}.
+
+ Parameters: ~
+ • {range} (`Range4`) `{ start_line, start_col, end_line, end_col }`
+ • {opts} (`table?`) A table with the following fields:
+ • {ignore_injections}? (`boolean`, default: `true`) Ignore
+ injected languages
+
+ Return: ~
+ (`TSNode?`)
+
LanguageTree:parse({range}) *LanguageTree:parse()*
Recursively parse all regions in the language tree using
|treesitter-parsers| for the corresponding languages and run injection
diff --git a/runtime/lua/vim/treesitter/languagetree.lua b/runtime/lua/vim/treesitter/languagetree.lua
index 3523ea95e0..03803f5869 100644
--- a/runtime/lua/vim/treesitter/languagetree.lua
+++ b/runtime/lua/vim/treesitter/languagetree.lua
@@ -1133,6 +1133,18 @@ function LanguageTree:tree_for_range(range, opts)
return nil
end
+--- Gets the smallest node that contains {range}.
+---
+---@param range Range4 `{ start_line, start_col, end_line, end_col }`
+---@param opts? vim.treesitter.LanguageTree.tree_for_range.Opts
+---@return TSNode?
+function LanguageTree:node_for_range(range, opts)
+ local tree = self:tree_for_range(range, opts)
+ if tree then
+ return tree:root():descendant_for_range(unpack(range))
+ end
+end
+
--- Gets the smallest named node that contains {range}.
---
---@param range Range4 `{ start_line, start_col, end_line, end_col }`
diff --git a/test/functional/treesitter/language_spec.lua b/test/functional/treesitter/language_spec.lua
index 40c974beee..e71c39244f 100644
--- a/test/functional/treesitter/language_spec.lua
+++ b/test/functional/treesitter/language_spec.lua
@@ -148,4 +148,15 @@ describe('treesitter language API', function()
eq('<node primitive_type>', exec_lua('return tostring(node)'))
end)
+
+ it('retrieve an anonymous node given a range', function()
+ insert([[vim.fn.input()]])
+
+ exec_lua([[
+ langtree = vim.treesitter.get_parser(0, "lua")
+ node = langtree:node_for_range({0, 3, 0, 3})
+ ]])
+
+ eq('.', exec_lua('return node:type()'))
+ end)
end)