diff --git a/runtime/lua/vim/treesitter/query.lua b/runtime/lua/vim/treesitter/query.lua index 3e18b8973a..a612870475 100644 --- a/runtime/lua/vim/treesitter/query.lua +++ b/runtime/lua/vim/treesitter/query.lua @@ -597,7 +597,8 @@ local predicate_handlers = { end for _, node in ipairs(nodes) do - if vim.list_contains({ unpack(predicate, 3) }, node:parent():type()) then + local parent = node:parent() + if parent and vim.list_contains({ unpack(predicate, 3) }, parent:type()) then return true end end diff --git a/test/functional/treesitter/query_spec.lua b/test/functional/treesitter/query_spec.lua index 04f2f519e9..f5de261d17 100644 --- a/test/functional/treesitter/query_spec.lua +++ b/test/functional/treesitter/query_spec.lua @@ -452,6 +452,26 @@ void ui_refresh(void) eq({}, result) end) + it('supports builtin predicate has-parent?', function() + insert([[ + int x = 123; + enum C { y = 124 };]]) + + local result = exec_lua( + get_query_result, + [[((number_literal) @literal (#has-parent? @literal "init_declarator"))]] + ) + eq({ { 'literal', 'number_literal', { 0, 8, 0, 11 }, '123' } }, result) + + -- The root node has no parent: the predicate does not match, rather than + -- erroring on the nil parent. + result = exec_lua( + get_query_result, + [[((translation_unit) @root (#has-parent? @root "translation_unit"))]] + ) + eq({}, result) + end) + it('allows loading query with escaped quotes and capture them `#{lua,vim}-match`?', function() insert('char* astring = "Hello World!";')