mirror of
https://github.com/neovim/neovim.git
synced 2024-12-20 03:05:11 -07:00
Merge pull request #15434 from Dkendal/feature-lua-treesitter-sibling
feat(treesitter): add next, prev sibling method
This commit is contained in:
commit
34b60ec894
@ -86,6 +86,18 @@ Node methods *lua-treesitter-node*
|
|||||||
tsnode:parent() *tsnode:parent()*
|
tsnode:parent() *tsnode:parent()*
|
||||||
Get the node's immediate 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()*
|
tsnode:iter_children() *tsnode:iter_children()*
|
||||||
Iterates over all the direct children of {tsnode}, regardless of
|
Iterates over all the direct children of {tsnode}, regardless of
|
||||||
wether they are named or not.
|
wether they are named or not.
|
||||||
|
@ -80,6 +80,10 @@ static struct luaL_Reg node_meta[] = {
|
|||||||
{ "parent", node_parent },
|
{ "parent", node_parent },
|
||||||
{ "iter_children", node_iter_children },
|
{ "iter_children", node_iter_children },
|
||||||
{ "_rawquery", node_rawquery },
|
{ "_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 }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -990,6 +994,50 @@ static int node_parent(lua_State *L)
|
|||||||
return 1;
|
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
|
/// assumes the match table being on top of the stack
|
||||||
static void set_match(lua_State *L, TSQueryMatch *match, int nodeidx)
|
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