mirror of
https://github.com/neovim/neovim
synced 2025-07-16 09:11:51 +00:00
fix(treesitter): TSNode:field()
returns all children with the given field
This commit is contained in:
committed by
Lewis Russell
parent
3e39250a79
commit
55b165ac15
@ -713,7 +713,7 @@ TSNode:extra() *TSNode:extra()*
|
|||||||
(`boolean`)
|
(`boolean`)
|
||||||
|
|
||||||
TSNode:field({name}) *TSNode:field()*
|
TSNode:field({name}) *TSNode:field()*
|
||||||
Returns a table of the nodes corresponding to the {name} field.
|
Returns a list of all the node's children that have the given field name.
|
||||||
|
|
||||||
Parameters: ~
|
Parameters: ~
|
||||||
• {name} (`string`)
|
• {name} (`string`)
|
||||||
|
@ -43,7 +43,7 @@ function TSNode:prev_named_sibling() end
|
|||||||
--- @return fun(): TSNode, string
|
--- @return fun(): TSNode, string
|
||||||
function TSNode:iter_children() end
|
function TSNode:iter_children() end
|
||||||
|
|
||||||
--- Returns a table of the nodes corresponding to the {name} field.
|
--- Returns a list of all the node's children that have the given field name.
|
||||||
--- @param name string
|
--- @param name string
|
||||||
--- @return TSNode[]
|
--- @return TSNode[]
|
||||||
function TSNode:field(name) end
|
function TSNode:field(name) end
|
||||||
|
@ -998,16 +998,21 @@ static int node_symbol(lua_State *L)
|
|||||||
static int node_field(lua_State *L)
|
static int node_field(lua_State *L)
|
||||||
{
|
{
|
||||||
TSNode node = node_check(L, 1);
|
TSNode node = node_check(L, 1);
|
||||||
|
uint32_t count = ts_node_child_count(node);
|
||||||
|
int curr_index = 0;
|
||||||
|
|
||||||
size_t name_len;
|
size_t name_len;
|
||||||
const char *field_name = luaL_checklstring(L, 2, &name_len);
|
const char *field_name = luaL_checklstring(L, 2, &name_len);
|
||||||
|
|
||||||
lua_newtable(L); // [table]
|
lua_newtable(L);
|
||||||
|
|
||||||
TSNode field = ts_node_child_by_field_name(node, field_name, (uint32_t)name_len);
|
for (uint32_t i = 0; i < count; i++) {
|
||||||
if (!ts_node_is_null(field)) {
|
const char *child_field_name = ts_node_field_name_for_child(node, i);
|
||||||
push_node(L, field, 1); // [table, node]
|
if (strequal(field_name, child_field_name)) {
|
||||||
lua_rawseti(L, -2, 1);
|
TSNode child = ts_node_child(node, i);
|
||||||
|
push_node(L, child, 1);
|
||||||
|
lua_rawseti(L, -2, ++curr_index);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -186,4 +186,23 @@ describe('treesitter node API', function()
|
|||||||
eq(lua_eval('value:type()'), lua_eval('declarator:child_with_descendant(value):type()'))
|
eq(lua_eval('value:type()'), lua_eval('declarator:child_with_descendant(value):type()'))
|
||||||
eq(vim.NIL, lua_eval('value:child_with_descendant(value)'))
|
eq(vim.NIL, lua_eval('value:child_with_descendant(value)'))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('gets all children with a given field name', function()
|
||||||
|
insert([[
|
||||||
|
function foo(a,b,c)
|
||||||
|
end
|
||||||
|
]])
|
||||||
|
|
||||||
|
exec_lua(function()
|
||||||
|
local tree = vim.treesitter.get_parser(0, 'lua'):parse()[1]
|
||||||
|
_G.parameters_node = assert(tree:root():named_descendant_for_range(0, 18, 0, 18))
|
||||||
|
_G.children_by_field = _G.parameters_node:field('name')
|
||||||
|
end)
|
||||||
|
|
||||||
|
eq('parameters', lua_eval('parameters_node:type()'))
|
||||||
|
eq(3, lua_eval('#children_by_field'))
|
||||||
|
eq('a', lua_eval('vim.treesitter.get_node_text(children_by_field[1], 0)'))
|
||||||
|
eq('b', lua_eval('vim.treesitter.get_node_text(children_by_field[2], 0)'))
|
||||||
|
eq('c', lua_eval('vim.treesitter.get_node_text(children_by_field[3], 0)'))
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
Reference in New Issue
Block a user