mirror of
https://github.com/neovim/neovim.git
synced 2025-09-08 04:18:18 +00:00
treesitter: add node:field() to get field children
This commit is contained in:
@@ -628,6 +628,9 @@ tsnode:iter_children() *tsnode:iter_children()*
|
|||||||
Returns the child node plus the eventual field name corresponding to
|
Returns the child node plus the eventual field name corresponding to
|
||||||
this child node.
|
this child node.
|
||||||
|
|
||||||
|
tsnode:field({name}) *tsnode:field()*
|
||||||
|
Returns a table of the nodes corresponding to the {name} field.
|
||||||
|
|
||||||
tsnode:child_count() *tsnode:child_count()*
|
tsnode:child_count() *tsnode:child_count()*
|
||||||
Get the node's number of children.
|
Get the node's number of children.
|
||||||
|
|
||||||
|
@@ -62,6 +62,7 @@ static struct luaL_Reg node_meta[] = {
|
|||||||
{ "end_", node_end },
|
{ "end_", node_end },
|
||||||
{ "type", node_type },
|
{ "type", node_type },
|
||||||
{ "symbol", node_symbol },
|
{ "symbol", node_symbol },
|
||||||
|
{ "field", node_field },
|
||||||
{ "named", node_named },
|
{ "named", node_named },
|
||||||
{ "missing", node_missing },
|
{ "missing", node_missing },
|
||||||
{ "has_error", node_has_error },
|
{ "has_error", node_has_error },
|
||||||
@@ -653,6 +654,34 @@ static int node_symbol(lua_State *L)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int node_field(lua_State *L)
|
||||||
|
{
|
||||||
|
TSNode node;
|
||||||
|
if (!node_check(L, 1, &node)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t name_len;
|
||||||
|
const char *field_name = luaL_checklstring(L, 2, &name_len);
|
||||||
|
|
||||||
|
TSTreeCursor cursor = ts_tree_cursor_new(node);
|
||||||
|
|
||||||
|
lua_newtable(L); // [table]
|
||||||
|
unsigned int curr_index = 0;
|
||||||
|
|
||||||
|
if (ts_tree_cursor_goto_first_child(&cursor)) {
|
||||||
|
do {
|
||||||
|
if (!STRCMP(field_name, ts_tree_cursor_current_field_name(&cursor))) {
|
||||||
|
push_node(L, ts_tree_cursor_current_node(&cursor), 1); // [table, node]
|
||||||
|
lua_rawseti(L, -2, ++curr_index);
|
||||||
|
}
|
||||||
|
} while (ts_tree_cursor_goto_next_sibling(&cursor));
|
||||||
|
}
|
||||||
|
|
||||||
|
ts_tree_cursor_delete(&cursor);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int node_named(lua_State *L)
|
static int node_named(lua_State *L)
|
||||||
{
|
{
|
||||||
TSNode node;
|
TSNode node;
|
||||||
|
@@ -151,6 +151,34 @@ void ui_refresh(void)
|
|||||||
}, res)
|
}, res)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('allows to get a child by field', function()
|
||||||
|
if not check_parser() then return end
|
||||||
|
|
||||||
|
insert(test_text);
|
||||||
|
|
||||||
|
local res = exec_lua([[
|
||||||
|
parser = vim.treesitter.get_parser(0, "c")
|
||||||
|
|
||||||
|
func_node = parser:parse():root():child(0)
|
||||||
|
|
||||||
|
local res = {}
|
||||||
|
for _, node in ipairs(func_node:field("type")) do
|
||||||
|
table.insert(res, {node:type(), node:range()})
|
||||||
|
end
|
||||||
|
return res
|
||||||
|
]])
|
||||||
|
|
||||||
|
eq({{ "primitive_type", 0, 0, 0, 4 }}, res)
|
||||||
|
|
||||||
|
local res_fail = exec_lua([[
|
||||||
|
parser = vim.treesitter.get_parser(0, "c")
|
||||||
|
|
||||||
|
return #func_node:field("foo") == 0
|
||||||
|
]])
|
||||||
|
|
||||||
|
assert(res_fail)
|
||||||
|
end)
|
||||||
|
|
||||||
local query = [[
|
local query = [[
|
||||||
((call_expression function: (identifier) @minfunc (argument_list (identifier) @min_id)) (eq? @minfunc "MIN"))
|
((call_expression function: (identifier) @minfunc (argument_list (identifier) @min_id)) (eq? @minfunc "MIN"))
|
||||||
"for" @keyword
|
"for" @keyword
|
||||||
|
Reference in New Issue
Block a user