mirror of
https://github.com/neovim/neovim.git
synced 2024-12-19 18:55:14 -07:00
feat(treesitter): add next, prev sibling method
Add tsnode methods to change to the next, previous, named or unnamed nodes.
This commit is contained in:
parent
2ae9ff1285
commit
140084180e
@ -86,6 +86,18 @@ Node methods *lua-treesitter-node*
|
||||
tsnode:parent() *tsnode:parent()*
|
||||
Get the node's immediate parent.
|
||||
|
||||
tsnode:next_sibling() *tsnode:next_sibling()*
|
||||
Get the node's next sibling.
|
||||
|
||||
tsnode:prev_sibling() *tsnode:prev_sibling()*
|
||||
Get the node's previous sibling.
|
||||
|
||||
tsnode:next_named_sibling() *tsnode:next_named_sibling()*
|
||||
Get the node's next named sibling.
|
||||
|
||||
tsnode:prev_named_sibling() *tsnode:prev_named_sibling()*
|
||||
Get the node's previous named sibling.
|
||||
|
||||
tsnode:iter_children() *tsnode:iter_children()*
|
||||
Iterates over all the direct children of {tsnode}, regardless of
|
||||
wether they are named or not.
|
||||
|
@ -80,6 +80,10 @@ static struct luaL_Reg node_meta[] = {
|
||||
{ "parent", node_parent },
|
||||
{ "iter_children", node_iter_children },
|
||||
{ "_rawquery", node_rawquery },
|
||||
{ "next_sibling", node_next_sibling },
|
||||
{ "prev_sibling", node_prev_sibling },
|
||||
{ "next_named_sibling", node_next_named_sibling },
|
||||
{ "prev_named_sibling", node_prev_named_sibling },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
@ -992,6 +996,50 @@ static int node_parent(lua_State *L)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int node_next_sibling(lua_State *L)
|
||||
{
|
||||
TSNode node;
|
||||
if (!node_check(L, 1, &node)) {
|
||||
return 0;
|
||||
}
|
||||
TSNode sibling = ts_node_next_sibling(node);
|
||||
push_node(L, sibling, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int node_prev_sibling(lua_State *L)
|
||||
{
|
||||
TSNode node;
|
||||
if (!node_check(L, 1, &node)) {
|
||||
return 0;
|
||||
}
|
||||
TSNode sibling = ts_node_prev_sibling(node);
|
||||
push_node(L, sibling, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int node_next_named_sibling(lua_State *L)
|
||||
{
|
||||
TSNode node;
|
||||
if (!node_check(L, 1, &node)) {
|
||||
return 0;
|
||||
}
|
||||
TSNode sibling = ts_node_next_named_sibling(node);
|
||||
push_node(L, sibling, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int node_prev_named_sibling(lua_State *L)
|
||||
{
|
||||
TSNode node;
|
||||
if (!node_check(L, 1, &node)) {
|
||||
return 0;
|
||||
}
|
||||
TSNode sibling = ts_node_prev_named_sibling(node);
|
||||
push_node(L, sibling, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/// assumes the match table being on top of the stack
|
||||
static void set_match(lua_State *L, TSQueryMatch *match, int nodeidx)
|
||||
{
|
||||
|
62
test/functional/treesitter/node_spec.lua
Normal file
62
test/functional/treesitter/node_spec.lua
Normal file
@ -0,0 +1,62 @@
|
||||
local helpers = require('test.functional.helpers')(after_each)
|
||||
|
||||
local clear = helpers.clear
|
||||
local eq = helpers.eq
|
||||
local exec_lua = helpers.exec_lua
|
||||
local insert = helpers.insert
|
||||
local pending_c_parser = helpers.pending_c_parser
|
||||
|
||||
before_each(clear)
|
||||
|
||||
local function lua_eval(lua_expr)
|
||||
return exec_lua("return " .. lua_expr)
|
||||
end
|
||||
|
||||
describe('treesitter node API', function()
|
||||
clear()
|
||||
|
||||
if pending_c_parser(pending) then
|
||||
return
|
||||
end
|
||||
|
||||
it('can move between siblings', function()
|
||||
insert([[
|
||||
int main(int x, int y, int z) {
|
||||
return x + y * z
|
||||
}
|
||||
]])
|
||||
|
||||
exec_lua([[
|
||||
query = require"vim.treesitter.query"
|
||||
parser = vim.treesitter.get_parser(0, "c")
|
||||
tree = parser:parse()[1]
|
||||
root = tree:root()
|
||||
lang = vim.treesitter.inspect_language('c')
|
||||
|
||||
function node_text(node)
|
||||
return query.get_node_text(node, 0)
|
||||
end
|
||||
]])
|
||||
|
||||
exec_lua 'node = root:descendant_for_range(0, 11, 0, 16)'
|
||||
eq('int x', lua_eval('node_text(node)'))
|
||||
|
||||
exec_lua 'node = node:next_sibling()'
|
||||
eq(',', lua_eval('node_text(node)'))
|
||||
|
||||
exec_lua 'node = node:next_sibling()'
|
||||
eq('int y', lua_eval('node_text(node)'))
|
||||
|
||||
exec_lua 'node = node:prev_sibling()'
|
||||
eq(',', lua_eval('node_text(node)'))
|
||||
|
||||
exec_lua 'node = node:prev_sibling()'
|
||||
eq('int x', lua_eval('node_text(node)'))
|
||||
|
||||
exec_lua 'node = node:next_named_sibling()'
|
||||
eq('int y', lua_eval('node_text(node)'))
|
||||
|
||||
exec_lua 'node = node:prev_named_sibling()'
|
||||
eq('int x', lua_eval('node_text(node)'))
|
||||
end)
|
||||
end)
|
Loading…
Reference in New Issue
Block a user