aboutsummaryrefslogtreecommitdiff
path: root/test/functional/treesitter
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2024-11-19 22:57:13 +0000
committerJosh Rahm <joshuarahm@gmail.com>2024-11-19 22:57:13 +0000
commit9be89f131f87608f224f0ee06d199fcd09d32176 (patch)
tree11022dcfa9e08cb4ac5581b16734196128688d48 /test/functional/treesitter
parentff7ed8f586589d620a806c3758fac4a47a8e7e15 (diff)
parent88085c2e80a7e3ac29aabb6b5420377eed99b8b6 (diff)
downloadrneovim-9be89f131f87608f224f0ee06d199fcd09d32176.tar.gz
rneovim-9be89f131f87608f224f0ee06d199fcd09d32176.tar.bz2
rneovim-9be89f131f87608f224f0ee06d199fcd09d32176.zip
Merge remote-tracking branch 'upstream/master' into mix_20240309
Diffstat (limited to 'test/functional/treesitter')
-rw-r--r--test/functional/treesitter/fold_spec.lua125
-rw-r--r--test/functional/treesitter/highlight_spec.lua429
-rw-r--r--test/functional/treesitter/inspect_tree_spec.lua81
-rw-r--r--test/functional/treesitter/language_spec.lua89
-rw-r--r--test/functional/treesitter/node_spec.lua103
-rw-r--r--test/functional/treesitter/parser_spec.lua487
-rw-r--r--test/functional/treesitter/query_spec.lua524
-rw-r--r--test/functional/treesitter/utils_spec.lua30
8 files changed, 1085 insertions, 783 deletions
diff --git a/test/functional/treesitter/fold_spec.lua b/test/functional/treesitter/fold_spec.lua
index a7f278aa01..24b085920c 100644
--- a/test/functional/treesitter/fold_spec.lua
+++ b/test/functional/treesitter/fold_spec.lua
@@ -48,13 +48,13 @@ void ui_refresh(void)
end
local function get_fold_levels()
- return exec_lua([[
- local res = {}
- for i = 1, vim.api.nvim_buf_line_count(0) do
- res[i] = vim.treesitter.foldexpr(i)
- end
- return res
- ]])
+ return exec_lua(function()
+ local res = {}
+ for i = 1, vim.api.nvim_buf_line_count(0) do
+ res[i] = vim.treesitter.foldexpr(i)
+ end
+ return res
+ end)
end
it('can compute fold levels', function()
@@ -246,9 +246,13 @@ function f()
end
-- comment]])
- exec_lua(
- [[vim.treesitter.query.set('lua', 'folds', '[(function_declaration) (parameters) (arguments)] @fold')]]
- )
+ exec_lua(function()
+ vim.treesitter.query.set(
+ 'lua',
+ 'folds',
+ '[(function_declaration) (parameters) (arguments)] @fold'
+ )
+ end)
parse('lua')
eq({
@@ -290,9 +294,13 @@ function f()
)
end]])
- exec_lua(
- [[vim.treesitter.query.set('lua', 'folds', '[(function_declaration) (function_definition) (parameters) (arguments)] @fold')]]
- )
+ exec_lua(function()
+ vim.treesitter.query.set(
+ 'lua',
+ 'folds',
+ '[(function_declaration) (function_definition) (parameters) (arguments)] @fold'
+ )
+ end)
parse('lua')
-- If fold1.stop = fold2.start, then move fold1's stop up so that fold2.start gets proper level.
@@ -333,9 +341,13 @@ function f(a)
end
end]])
- exec_lua(
- [[vim.treesitter.query.set('lua', 'folds', '[(if_statement) (function_declaration) (parameters) (arguments) (table_constructor)] @fold')]]
- )
+ exec_lua(function()
+ vim.treesitter.query.set(
+ 'lua',
+ 'folds',
+ '[(if_statement) (function_declaration) (parameters) (arguments) (table_constructor)] @fold'
+ )
+ end)
parse('lua')
eq({
@@ -408,15 +420,15 @@ t3]])
it('handles quantified patterns', function()
insert([[
-import hello
-import hello
-import hello
-import hello
-import hello
-import hello]])
-
- exec_lua([[vim.treesitter.query.set('python', 'folds', '(import_statement)+ @fold')]])
- parse('python')
+-- hello
+-- hello
+-- hello
+-- hello
+-- hello
+-- hello]])
+
+ exec_lua([[vim.treesitter.query.set('lua', 'folds', '(comment)+ @fold')]])
+ parse('lua')
eq({
[1] = '>1',
@@ -646,6 +658,67 @@ import hello]])
}
end)
+ it('does not extend closed fold with `o`/`O`', function()
+ local screen = Screen.new(60, 24)
+ screen:attach()
+
+ insert(test_text)
+ parse('c')
+ command([[set foldmethod=expr foldexpr=v:lua.vim.treesitter.foldexpr() foldcolumn=1]])
+
+ feed('5ggzco')
+ screen:expect({
+ grid = [[
+ {7:-}void ui_refresh(void) |
+ {7:│}{ |
+ {7:│} int width = INT_MAX, height = INT_MAX; |
+ {7:│} bool ext_widgets[kUIExtCount]; |
+ {7:+}{13:+--- 3 lines: for (UIExtension i = 0; (int)i < kUIExtCount}|
+ {7:│}^ |
+ {7:│} |
+ {7:│} bool inclusive = ui_override(); |
+ {7:-} for (size_t i = 0; i < ui_count; i++) { |
+ {7:2} UI *ui = uis[i]; |
+ {7:2} width = MIN(ui->width, width); |
+ {7:2} height = MIN(ui->height, height); |
+ {7:2} foo = BAR(ui->bazaar, bazaar); |
+ {7:-} for (UIExtension j = 0; (int)j < kUIExtCount; j++) { |
+ {7:3} ext_widgets[j] &= (ui->ui_ext[j] || inclusive); |
+ {7:3} } |
+ {7:2} } |
+ {7:│}} |
+ {1:~ }|*5
+ {5:-- INSERT --} |
+ ]],
+ })
+
+ feed('<Esc>O')
+ screen:expect({
+ grid = [[
+ {7:-}void ui_refresh(void) |
+ {7:│}{ |
+ {7:│} int width = INT_MAX, height = INT_MAX; |
+ {7:│} bool ext_widgets[kUIExtCount]; |
+ {7:+}{13:+--- 3 lines: for (UIExtension i = 0; (int)i < kUIExtCount}|
+ {7:│}^ |
+ {7:│} |*2
+ {7:│} bool inclusive = ui_override(); |
+ {7:-} for (size_t i = 0; i < ui_count; i++) { |
+ {7:2} UI *ui = uis[i]; |
+ {7:2} width = MIN(ui->width, width); |
+ {7:2} height = MIN(ui->height, height); |
+ {7:2} foo = BAR(ui->bazaar, bazaar); |
+ {7:-} for (UIExtension j = 0; (int)j < kUIExtCount; j++) { |
+ {7:3} ext_widgets[j] &= (ui->ui_ext[j] || inclusive); |
+ {7:3} } |
+ {7:2} } |
+ {7:│}} |
+ {1:~ }|*4
+ {5:-- INSERT --} |
+ ]],
+ })
+ end)
+
it("doesn't open folds that are not touched", function()
local screen = Screen.new(40, 8)
screen:set_default_attr_ids({
@@ -674,7 +747,7 @@ t2]])
grid = [[
{1:-}# h1 |
{1:│}t1 |
- {1:│}^ |
+ {1:-}^ |
{1:+}{2:+-- 2 lines: # h2·····················}|
{3:~ }|*3
{4:-- INSERT --} |
diff --git a/test/functional/treesitter/highlight_spec.lua b/test/functional/treesitter/highlight_spec.lua
index 69984b3233..b5a6cb5c17 100644
--- a/test/functional/treesitter/highlight_spec.lua
+++ b/test/functional/treesitter/highlight_spec.lua
@@ -8,10 +8,9 @@ local exec_lua = n.exec_lua
local feed = n.feed
local command = n.command
local api = n.api
+local fn = n.fn
local eq = t.eq
-before_each(clear)
-
local hl_query_c = [[
(ERROR) @error
@@ -65,6 +64,46 @@ static int nlua_schedule(lua_State *const lstate)
return 0;
}]]
+local hl_grid_legacy_c = [[
+ {2:^/// Schedule Lua callback on main loop's event queue} |
+ {3:static} {3:int} nlua_schedule(lua_State *{3:const} lstate) |
+ { |
+ {4:if} (lua_type(lstate, {5:1}) != LUA_TFUNCTION |
+ || lstate != lstate) { |
+ lua_pushliteral(lstate, {5:"vim.schedule: expected function"}); |
+ {4:return} lua_error(lstate); |
+ } |
+ |
+ LuaRef cb = nlua_ref(lstate, {5:1}); |
+ |
+ multiqueue_put(main_loop.events, nlua_schedule_event, |
+ {5:1}, ({3:void} *)({3:ptrdiff_t})cb); |
+ {4:return} {5:0}; |
+ } |
+ {1:~ }|*2
+ |
+]]
+
+local hl_grid_ts_c = [[
+ {2:^/// Schedule Lua callback on main loop's event queue} |
+ {3:static} {3:int} {11:nlua_schedule}({3:lua_State} *{3:const} lstate) |
+ { |
+ {4:if} ({11:lua_type}(lstate, {5:1}) != {5:LUA_TFUNCTION} |
+ || {6:lstate} != {6:lstate}) { |
+ {11:lua_pushliteral}(lstate, {5:"vim.schedule: expected function"}); |
+ {4:return} {11:lua_error}(lstate); |
+ } |
+ |
+ {7:LuaRef} cb = {11:nlua_ref}(lstate, {5:1}); |
+ |
+ multiqueue_put(main_loop.events, {11:nlua_schedule_event}, |
+ {5:1}, ({3:void} *)({3:ptrdiff_t})cb); |
+ {4:return} {5:0}; |
+ } |
+ {1:~ }|*2
+ |
+]]
+
local test_text_c = [[
void ui_refresh(void)
{
@@ -117,9 +156,10 @@ local injection_grid_expected_c = [[
]]
describe('treesitter highlighting (C)', function()
- local screen
+ local screen --- @type test.functional.ui.screen
before_each(function()
+ clear()
screen = Screen.new(65, 18)
screen:attach()
screen:set_default_attr_ids {
@@ -136,16 +176,49 @@ describe('treesitter highlighting (C)', function()
[11] = { foreground = Screen.colors.Cyan4 },
}
- exec_lua([[ hl_query = ... ]], hl_query_c)
command [[ hi link @error ErrorMsg ]]
command [[ hi link @warning WarningMsg ]]
end)
+ it('starting and stopping treesitter highlight works', function()
+ command('setfiletype c | syntax on')
+ fn.setreg('r', hl_text_c)
+ feed('i<C-R><C-O>r<Esc>gg')
+ -- legacy syntax highlighting is used by default
+ screen:expect(hl_grid_legacy_c)
+
+ exec_lua(function()
+ vim.treesitter.query.set('c', 'highlights', hl_query_c)
+ vim.treesitter.start()
+ end)
+ -- treesitter highlighting is used
+ screen:expect(hl_grid_ts_c)
+
+ exec_lua(function()
+ vim.treesitter.stop()
+ end)
+ -- legacy syntax highlighting is used
+ screen:expect(hl_grid_legacy_c)
+
+ exec_lua(function()
+ vim.treesitter.start()
+ end)
+ -- treesitter highlighting is used
+ screen:expect(hl_grid_ts_c)
+
+ exec_lua(function()
+ vim.treesitter.stop()
+ end)
+ -- legacy syntax highlighting is used
+ screen:expect(hl_grid_legacy_c)
+ end)
+
it('is updated with edits', function()
insert(hl_text_c)
+ feed('gg')
screen:expect {
grid = [[
- /// Schedule Lua callback on main loop's event queue |
+ ^/// Schedule Lua callback on main loop's event queue |
static int nlua_schedule(lua_State *const lstate) |
{ |
if (lua_type(lstate, 1) != LUA_TFUNCTION |
@@ -159,38 +232,18 @@ describe('treesitter highlighting (C)', function()
multiqueue_put(main_loop.events, nlua_schedule_event, |
1, (void *)(ptrdiff_t)cb); |
return 0; |
- ^} |
+ } |
{1:~ }|*2
|
]],
}
- exec_lua [[
- local parser = vim.treesitter.get_parser(0, "c")
+ exec_lua(function()
+ local parser = vim.treesitter.get_parser(0, 'c')
local highlighter = vim.treesitter.highlighter
- test_hl = highlighter.new(parser, {queries = {c = hl_query}})
- ]]
- screen:expect {
- grid = [[
- {2:/// Schedule Lua callback on main loop's event queue} |
- {3:static} {3:int} {11:nlua_schedule}({3:lua_State} *{3:const} lstate) |
- { |
- {4:if} ({11:lua_type}(lstate, {5:1}) != {5:LUA_TFUNCTION} |
- || {6:lstate} != {6:lstate}) { |
- {11:lua_pushliteral}(lstate, {5:"vim.schedule: expected function"}); |
- {4:return} {11:lua_error}(lstate); |
- } |
- |
- {7:LuaRef} cb = {11:nlua_ref}(lstate, {5:1}); |
- |
- multiqueue_put(main_loop.events, {11:nlua_schedule_event}, |
- {5:1}, ({3:void} *)({3:ptrdiff_t})cb); |
- {4:return} {5:0}; |
- ^} |
- {1:~ }|*2
- |
- ]],
- }
+ highlighter.new(parser, { queries = { c = hl_query_c } })
+ end)
+ screen:expect(hl_grid_ts_c)
feed('5Goc<esc>dd')
@@ -316,10 +369,10 @@ describe('treesitter highlighting (C)', function()
it('is updated with :sort', function()
insert(test_text_c)
- exec_lua [[
- local parser = vim.treesitter.get_parser(0, "c")
- test_hl = vim.treesitter.highlighter.new(parser, {queries = {c = hl_query}})
- ]]
+ exec_lua(function()
+ local parser = vim.treesitter.get_parser(0, 'c')
+ vim.treesitter.highlighter.new(parser, { queries = { c = hl_query_c } })
+ end)
screen:expect {
grid = [[
{3:int} width = {5:INT_MAX}, height = {5:INT_MAX}; |
@@ -422,19 +475,19 @@ describe('treesitter highlighting (C)', function()
]],
}
- exec_lua [[
- parser = vim.treesitter.get_parser(0, "c")
- query = vim.treesitter.query.parse("c", "(declaration) @decl")
+ exec_lua(function()
+ local parser = vim.treesitter.get_parser(0, 'c')
+ local query = vim.treesitter.query.parse('c', '(declaration) @decl')
local nodes = {}
for _, node in query:iter_captures(parser:parse()[1]:root(), 0, 0, 19) do
table.insert(nodes, node)
end
- parser:set_included_regions({nodes})
+ parser:set_included_regions({ nodes })
- local hl = vim.treesitter.highlighter.new(parser, {queries = {c = "(identifier) @type"}})
- ]]
+ vim.treesitter.highlighter.new(parser, { queries = { c = '(identifier) @type' } })
+ end)
screen:expect {
grid = [[
@@ -465,13 +518,15 @@ describe('treesitter highlighting (C)', function()
screen:expect { grid = injection_grid_c }
- exec_lua [[
- local parser = vim.treesitter.get_parser(0, "c", {
- injections = {c = '(preproc_def (preproc_arg) @injection.content (#set! injection.language "c")) (preproc_function_def value: (preproc_arg) @injection.content (#set! injection.language "c"))'}
+ exec_lua(function()
+ local parser = vim.treesitter.get_parser(0, 'c', {
+ injections = {
+ c = '(preproc_def (preproc_arg) @injection.content (#set! injection.language "c")) (preproc_function_def value: (preproc_arg) @injection.content (#set! injection.language "c"))',
+ },
})
local highlighter = vim.treesitter.highlighter
- test_hl = highlighter.new(parser, {queries = {c = hl_query}})
- ]]
+ highlighter.new(parser, { queries = { c = hl_query_c } })
+ end)
screen:expect { grid = injection_grid_expected_c }
end)
@@ -481,14 +536,16 @@ describe('treesitter highlighting (C)', function()
screen:expect { grid = injection_grid_c }
- exec_lua [[
- vim.treesitter.language.register("c", "foo")
- local parser = vim.treesitter.get_parser(0, "c", {
- injections = {c = '(preproc_def (preproc_arg) @injection.content (#set! injection.language "foo")) (preproc_function_def value: (preproc_arg) @injection.content (#set! injection.language "foo"))'}
+ exec_lua(function()
+ vim.treesitter.language.register('c', 'foo')
+ local parser = vim.treesitter.get_parser(0, 'c', {
+ injections = {
+ c = '(preproc_def (preproc_arg) @injection.content (#set! injection.language "foo")) (preproc_function_def value: (preproc_arg) @injection.content (#set! injection.language "foo"))',
+ },
})
local highlighter = vim.treesitter.highlighter
- test_hl = highlighter.new(parser, {queries = {c = hl_query}})
- ]]
+ highlighter.new(parser, { queries = { c = hl_query_c } })
+ end)
screen:expect { grid = injection_grid_expected_c }
end)
@@ -502,13 +559,14 @@ describe('treesitter highlighting (C)', function()
}
]])
- exec_lua [[
- local injection_query = '(preproc_def (preproc_arg) @injection.content (#set! injection.language "c")) (preproc_function_def value: (preproc_arg) @injection.content (#set! injection.language "c"))'
- vim.treesitter.query.set("c", "highlights", hl_query)
- vim.treesitter.query.set("c", "injections", injection_query)
+ exec_lua(function()
+ local injection_query =
+ '(preproc_def (preproc_arg) @injection.content (#set! injection.language "c")) (preproc_function_def value: (preproc_arg) @injection.content (#set! injection.language "c"))'
+ vim.treesitter.query.set('c', 'highlights', hl_query_c)
+ vim.treesitter.query.set('c', 'injections', injection_query)
- vim.treesitter.highlighter.new(vim.treesitter.get_parser(0, "c"))
- ]]
+ vim.treesitter.highlighter.new(vim.treesitter.get_parser(0, 'c'))
+ end)
screen:expect {
grid = [[
@@ -526,40 +584,21 @@ describe('treesitter highlighting (C)', function()
it('supports highlighting with custom highlight groups', function()
insert(hl_text_c)
+ feed('gg')
- exec_lua [[
- local parser = vim.treesitter.get_parser(0, "c")
- test_hl = vim.treesitter.highlighter.new(parser, {queries = {c = hl_query}})
- ]]
+ exec_lua(function()
+ local parser = vim.treesitter.get_parser(0, 'c')
+ vim.treesitter.highlighter.new(parser, { queries = { c = hl_query_c } })
+ end)
- screen:expect {
- grid = [[
- {2:/// Schedule Lua callback on main loop's event queue} |
- {3:static} {3:int} {11:nlua_schedule}({3:lua_State} *{3:const} lstate) |
- { |
- {4:if} ({11:lua_type}(lstate, {5:1}) != {5:LUA_TFUNCTION} |
- || {6:lstate} != {6:lstate}) { |
- {11:lua_pushliteral}(lstate, {5:"vim.schedule: expected function"}); |
- {4:return} {11:lua_error}(lstate); |
- } |
- |
- {7:LuaRef} cb = {11:nlua_ref}(lstate, {5:1}); |
- |
- multiqueue_put(main_loop.events, {11:nlua_schedule_event}, |
- {5:1}, ({3:void} *)({3:ptrdiff_t})cb); |
- {4:return} {5:0}; |
- ^} |
- {1:~ }|*2
- |
- ]],
- }
+ screen:expect(hl_grid_ts_c)
-- This will change ONLY the literal strings to look like comments
-- The only literal string is the "vim.schedule: expected function" in this test.
exec_lua [[vim.cmd("highlight link @string.nonexistent_specializer comment")]]
screen:expect {
grid = [[
- {2:/// Schedule Lua callback on main loop's event queue} |
+ {2:^/// Schedule Lua callback on main loop's event queue} |
{3:static} {3:int} {11:nlua_schedule}({3:lua_State} *{3:const} lstate) |
{ |
{4:if} ({11:lua_type}(lstate, {5:1}) != {5:LUA_TFUNCTION} |
@@ -573,7 +612,7 @@ describe('treesitter highlighting (C)', function()
multiqueue_put(main_loop.events, {11:nlua_schedule_event}, |
{5:1}, ({3:void} *)({3:ptrdiff_t})cb); |
{4:return} {5:0}; |
- ^} |
+ } |
{1:~ }|*2
|
]],
@@ -590,10 +629,14 @@ describe('treesitter highlighting (C)', function()
}
]])
- exec_lua [[
- local parser = vim.treesitter.get_parser(0, "c")
- test_hl = vim.treesitter.highlighter.new(parser, {queries = {c = hl_query..'\n((translation_unit) @constant (#set! "priority" 101))\n'}})
- ]]
+ exec_lua(function()
+ local parser = vim.treesitter.get_parser(0, 'c')
+ vim.treesitter.highlighter.new(parser, {
+ queries = {
+ c = hl_query_c .. '\n((translation_unit) @constant (#set! "priority" 101))\n',
+ },
+ })
+ end)
-- expect everything to have Constant highlight
screen:expect {
grid = [[
@@ -640,11 +683,14 @@ describe('treesitter highlighting (C)', function()
hi link @foo.bar Type
hi link @foo String
]]
- exec_lua [[
- local parser = vim.treesitter.get_parser(0, "c", {})
- local highlighter = vim.treesitter.highlighter
- test_hl = highlighter.new(parser, {queries = {c = "(primitive_type) @foo.bar (string_literal) @foo"}})
- ]]
+ exec_lua(function()
+ local parser = vim.treesitter.get_parser(0, 'c', {})
+ local highlighter = vim.treesitter.highlighter
+ highlighter.new(
+ parser,
+ { queries = { c = '(primitive_type) @foo.bar (string_literal) @foo' } }
+ )
+ end)
screen:expect {
grid = [[
@@ -672,10 +718,12 @@ describe('treesitter highlighting (C)', function()
insert(hl_text_c)
-- conceal can be empty or a single cchar.
- exec_lua [=[
+ exec_lua(function()
vim.opt.cole = 2
- local parser = vim.treesitter.get_parser(0, "c")
- test_hl = vim.treesitter.highlighter.new(parser, {queries = {c = [[
+ local parser = vim.treesitter.get_parser(0, 'c')
+ vim.treesitter.highlighter.new(parser, {
+ queries = {
+ c = [[
("static" @keyword
(#set! conceal "R"))
@@ -688,8 +736,10 @@ describe('treesitter highlighting (C)', function()
arguments: (argument_list) @arguments)
(#eq? @function "multiqueue_put")
(#set! @function conceal "V"))
- ]]}})
- ]=]
+ ]],
+ },
+ })
+ end)
screen:expect {
grid = [[
@@ -746,11 +796,11 @@ describe('treesitter highlighting (C)', function()
int z = 6;
]])
- exec_lua([[
+ exec_lua(function()
local query = '((declaration)+ @string)'
vim.treesitter.query.set('c', 'highlights', query)
vim.treesitter.highlighter.new(vim.treesitter.get_parser(0, 'c'))
- ]])
+ end)
screen:expect {
grid = [[
@@ -776,14 +826,10 @@ describe('treesitter highlighting (C)', function()
declarator: (pointer_declarator) @variable.parameter)
]]
- exec_lua(
- [[
- local query = ...
+ exec_lua(function()
vim.treesitter.query.set('c', 'highlights', query)
vim.treesitter.highlighter.new(vim.treesitter.get_parser(0, 'c'))
- ]],
- query
- )
+ end)
screen:expect {
grid = [[
@@ -800,6 +846,7 @@ describe('treesitter highlighting (lua)', function()
local screen
before_each(function()
+ clear()
screen = Screen.new(65, 18)
screen:attach()
screen:set_default_attr_ids {
@@ -817,10 +864,10 @@ describe('treesitter highlighting (lua)', function()
ffi.cdef("int (*fun)(int, char *);")
]]
- exec_lua [[
+ exec_lua(function()
vim.bo.filetype = 'lua'
vim.treesitter.start()
- ]]
+ end)
screen:expect {
grid = [[
@@ -838,6 +885,7 @@ describe('treesitter highlighting (help)', function()
local screen
before_each(function()
+ clear()
screen = Screen.new(40, 6)
screen:attach()
screen:set_default_attr_ids {
@@ -846,9 +894,45 @@ describe('treesitter highlighting (help)', function()
[3] = { bold = true, foreground = Screen.colors.Brown },
[4] = { foreground = Screen.colors.Cyan4 },
[5] = { foreground = Screen.colors.Magenta1 },
+ title = { bold = true, foreground = Screen.colors.Magenta1 },
+ h1_delim = { nocombine = true, underdouble = true },
+ h2_delim = { nocombine = true, underline = true },
}
end)
+ it('defaults in vimdoc/highlights.scm', function()
+ -- Avoid regressions when syncing upstream vimdoc queries.
+
+ insert [[
+ ==============================================================================
+ NVIM DOCUMENTATION
+
+ ------------------------------------------------------------------------------
+ ABOUT NVIM *tag-1* *tag-2*
+
+ |news| News
+ |nvim| NVim
+ ]]
+
+ feed('gg')
+ exec_lua(function()
+ vim.wo.wrap = false
+ vim.bo.filetype = 'help'
+ vim.treesitter.start()
+ end)
+
+ screen:expect({
+ grid = [[
+ {h1_delim:^========================================}|
+ {title:NVIM DOCUMENTATION} |
+ |
+ {h2_delim:----------------------------------------}|
+ {title:ABOUT NVIM} |
+ |
+ ]],
+ })
+ end)
+
it('correctly redraws added/removed injections', function()
insert [[
>ruby
@@ -857,10 +941,10 @@ describe('treesitter highlighting (help)', function()
<
]]
- exec_lua [[
+ exec_lua(function()
vim.bo.filetype = 'help'
vim.treesitter.start()
- ]]
+ end)
screen:expect {
grid = [[
@@ -912,15 +996,15 @@ describe('treesitter highlighting (help)', function()
]]
]=])
- exec_lua [[
- parser = vim.treesitter.get_parser(0, "lua", {
+ exec_lua(function()
+ local parser = vim.treesitter.get_parser(0, 'lua', {
injections = {
- lua = '(string content: (_) @injection.content (#set! injection.language lua))'
- }
+ lua = '(string content: (_) @injection.content (#set! injection.language lua))',
+ },
})
vim.treesitter.highlighter.new(parser)
- ]]
+ end)
screen:expect {
grid = [=[
@@ -936,9 +1020,10 @@ describe('treesitter highlighting (help)', function()
end)
describe('treesitter highlighting (nested injections)', function()
- local screen
+ local screen --- @type test.functional.ui.screen
before_each(function()
+ clear()
screen = Screen.new(80, 7)
screen:attach()
screen:set_default_attr_ids {
@@ -964,11 +1049,11 @@ vim.cmd([[
]])
]=]
- exec_lua [[
+ exec_lua(function()
vim.opt.scrolloff = 0
vim.bo.filetype = 'lua'
vim.treesitter.start()
- ]]
+ end)
-- invalidate the language tree
feed('ggi--[[<ESC>04x')
@@ -1006,41 +1091,93 @@ describe('treesitter highlighting (markdown)', function()
local screen
before_each(function()
+ clear()
screen = Screen.new(40, 6)
screen:attach()
- screen:set_default_attr_ids {
- [1] = { foreground = Screen.colors.Blue1 },
- [2] = { bold = true, foreground = Screen.colors.Blue1 },
- [3] = { bold = true, foreground = Screen.colors.Brown },
- [4] = { foreground = Screen.colors.Cyan4 },
- [5] = { foreground = Screen.colors.Magenta1 },
- }
+ exec_lua(function()
+ vim.bo.filetype = 'markdown'
+ vim.treesitter.start()
+ end)
end)
it('supports hyperlinks', function()
local url = 'https://example.com'
insert(string.format('[This link text](%s) is a hyperlink.', url))
- exec_lua([[
- vim.bo.filetype = 'markdown'
- vim.treesitter.start()
- ]])
+ screen:add_extra_attr_ids({
+ [100] = { foreground = Screen.colors.DarkCyan, url = 'https://example.com' },
+ [101] = {
+ foreground = Screen.colors.SlateBlue,
+ url = 'https://example.com',
+ underline = true,
+ },
+ })
+ screen:expect({
+ grid = [[
+ {25:[}{100:This link text}{25:](}{101:https://example.com}{25:)} is|
+ a hyperlink^. |
+ {1:~ }|*3
+ |
+ ]],
+ })
+ end)
- screen:expect {
+ it('works with spellchecked and smoothscrolled topline', function()
+ insert([[
+- $f(0)=\sum_{k=1}^{\infty}\frac{2}{\pi^{2}k^{2}}+\lim_{w \to 0}x$.
+
+```c
+printf('Hello World!');
+```
+ ]])
+ command('set spell smoothscroll')
+ feed('gg<C-E>')
+ screen:add_extra_attr_ids({ [100] = { undercurl = true, special = Screen.colors.Red } })
+ screen:expect({
grid = [[
- {4:[}{6:This link text}{4:](}{7:https://example.com}{4:)} is|
- a hyperlink^. |
- {2:~ }|*3
- |
- ]],
- attr_ids = {
- [1] = { foreground = Screen.colors.Blue1 },
- [2] = { bold = true, foreground = Screen.colors.Blue1 },
- [3] = { bold = true, foreground = Screen.colors.Brown },
- [4] = { foreground = Screen.colors.Cyan4 },
- [5] = { foreground = Screen.colors.Magenta },
- [6] = { foreground = Screen.colors.Cyan4, url = url },
- [7] = { underline = true, foreground = Screen.colors.SlateBlue },
- },
- }
+ {1:<<<}k^{2}}+\{100:lim}_{w \to 0}x$^. |
+ |
+ {18:```}{15:c} |
+ {25:printf}{16:(}{26:'Hello World!'}{16:);} |
+ {18:```} |
+ |
+ ]],
+ })
end)
end)
+
+it('starting and stopping treesitter highlight in init.lua works #29541', function()
+ t.write_file(
+ 'Xinit.lua',
+ [[
+ vim.bo.ft = 'c'
+ vim.treesitter.start()
+ vim.treesitter.stop()
+ ]]
+ )
+ finally(function()
+ os.remove('Xinit.lua')
+ end)
+ clear({ args = { '-u', 'Xinit.lua' } })
+ eq('', api.nvim_get_vvar('errmsg'))
+
+ local screen = Screen.new(65, 18)
+ screen:attach()
+ screen:set_default_attr_ids {
+ [1] = { bold = true, foreground = Screen.colors.Blue1 },
+ [2] = { foreground = Screen.colors.Blue1 },
+ [3] = { bold = true, foreground = Screen.colors.SeaGreen4 },
+ [4] = { bold = true, foreground = Screen.colors.Brown },
+ [5] = { foreground = Screen.colors.Magenta },
+ [6] = { foreground = Screen.colors.Red },
+ [7] = { bold = true, foreground = Screen.colors.SlateBlue },
+ [8] = { foreground = Screen.colors.Grey100, background = Screen.colors.Red },
+ [9] = { foreground = Screen.colors.Magenta, background = Screen.colors.Red },
+ [10] = { foreground = Screen.colors.Red, background = Screen.colors.Red },
+ [11] = { foreground = Screen.colors.Cyan4 },
+ }
+
+ fn.setreg('r', hl_text_c)
+ feed('i<C-R><C-O>r<Esc>gg')
+ -- legacy syntax highlighting is used
+ screen:expect(hl_grid_legacy_c)
+end)
diff --git a/test/functional/treesitter/inspect_tree_spec.lua b/test/functional/treesitter/inspect_tree_spec.lua
index f5acfe7c4a..1f7d15cc96 100644
--- a/test/functional/treesitter/inspect_tree_spec.lua
+++ b/test/functional/treesitter/inspect_tree_spec.lua
@@ -22,10 +22,10 @@ describe('vim.treesitter.inspect_tree', function()
print()
]])
- exec_lua([[
+ exec_lua(function()
vim.treesitter.start(0, 'lua')
vim.treesitter.inspect_tree()
- ]])
+ end)
expect_tree [[
(chunk ; [0, 0] - [2, 0]
@@ -37,22 +37,26 @@ describe('vim.treesitter.inspect_tree', function()
it('can toggle to show anonymous nodes', function()
insert([[
- print()
+ print('hello')
]])
- exec_lua([[
+ exec_lua(function()
vim.treesitter.start(0, 'lua')
vim.treesitter.inspect_tree()
- ]])
+ end)
feed('a')
expect_tree [[
(chunk ; [0, 0] - [2, 0]
- (function_call ; [0, 0] - [0, 7]
+ (function_call ; [0, 0] - [0, 14]
name: (identifier) ; [0, 0] - [0, 5]
- arguments: (arguments ; [0, 5] - [0, 7]
+ arguments: (arguments ; [0, 5] - [0, 14]
"(" ; [0, 5] - [0, 6]
- ")"))) ; [0, 6] - [0, 7]
+ (string ; [0, 6] - [0, 13]
+ start: "'" ; [0, 6] - [0, 7]
+ content: (string_content) ; [0, 7] - [0, 12]
+ end: "'") ; [0, 12] - [0, 13]
+ ")"))) ; [0, 13] - [0, 14]
]]
end)
@@ -63,11 +67,11 @@ describe('vim.treesitter.inspect_tree', function()
```
]])
- exec_lua([[
+ exec_lua(function()
vim.treesitter.start(0, 'markdown')
vim.treesitter.get_parser():parse()
vim.treesitter.inspect_tree()
- ]])
+ end)
expect_tree [[
(document ; [0, 0] - [4, 0]
@@ -92,11 +96,11 @@ describe('vim.treesitter.inspect_tree', function()
```
]])
- exec_lua([[
+ exec_lua(function()
vim.treesitter.start(0, 'markdown')
vim.treesitter.get_parser():parse()
vim.treesitter.inspect_tree()
- ]])
+ end)
feed('I')
expect_tree [[
@@ -114,4 +118,57 @@ describe('vim.treesitter.inspect_tree', function()
(fenced_code_block_delimiter)))) ; [2, 0] - [2, 3] markdown
]]
end)
+
+ it('updates source and tree buffer windows and closes them correctly', function()
+ insert([[
+ print()
+ ]])
+
+ -- setup two windows for the source buffer
+ exec_lua(function()
+ _G.source_win = vim.api.nvim_get_current_win()
+ vim.api.nvim_open_win(0, false, {
+ win = 0,
+ split = 'left',
+ })
+ end)
+
+ -- setup three windows for the tree buffer
+ exec_lua(function()
+ vim.treesitter.start(0, 'lua')
+ vim.treesitter.inspect_tree()
+ _G.tree_win = vim.api.nvim_get_current_win()
+ _G.tree_win_copy_1 = vim.api.nvim_open_win(0, false, {
+ win = 0,
+ split = 'left',
+ })
+ _G.tree_win_copy_2 = vim.api.nvim_open_win(0, false, {
+ win = 0,
+ split = 'left',
+ })
+ end)
+
+ -- close original source window
+ exec_lua('vim.api.nvim_win_close(source_win, false)')
+
+ -- navigates correctly to the remaining source buffer window
+ feed('<CR>')
+ eq('', n.api.nvim_get_vvar('errmsg'))
+
+ -- close original tree window
+ exec_lua(function()
+ vim.api.nvim_set_current_win(_G.tree_win_copy_1)
+ vim.api.nvim_win_close(_G.tree_win, false)
+ end)
+
+ -- navigates correctly to the remaining source buffer window
+ feed('<CR>')
+ eq('', n.api.nvim_get_vvar('errmsg'))
+
+ -- close source buffer window and all remaining tree windows
+ t.pcall_err(exec_lua, 'vim.api.nvim_win_close(0, false)')
+
+ eq(false, exec_lua('return vim.api.nvim_win_is_valid(tree_win_copy_1)'))
+ eq(false, exec_lua('return vim.api.nvim_win_is_valid(tree_win_copy_2)'))
+ end)
end)
diff --git a/test/functional/treesitter/language_spec.lua b/test/functional/treesitter/language_spec.lua
index 40c974beee..e1e34fcecc 100644
--- a/test/functional/treesitter/language_spec.lua
+++ b/test/functional/treesitter/language_spec.lua
@@ -8,6 +8,7 @@ local exec_lua = n.exec_lua
local pcall_err = t.pcall_err
local matches = t.matches
local insert = n.insert
+local NIL = vim.NIL
before_each(clear)
@@ -15,10 +16,12 @@ describe('treesitter language API', function()
-- error tests not requiring a parser library
it('handles missing language', function()
eq(
- ".../language.lua:0: no parser for 'borklang' language, see :help treesitter-parsers",
+ '.../treesitter.lua:0: Parser could not be created for buffer 1 and language "borklang"',
pcall_err(exec_lua, "parser = vim.treesitter.get_parser(0, 'borklang')")
)
+ eq(NIL, exec_lua("return vim.treesitter.get_parser(0, 'borklang', { error = false })"))
+
-- actual message depends on platform
matches(
"Failed to load parser for language 'borklang': uv_dlopen: .+",
@@ -28,37 +31,33 @@ describe('treesitter language API', function()
)
)
- eq(false, exec_lua("return pcall(vim.treesitter.language.add, 'borklang')"))
+ eq(NIL, exec_lua("return vim.treesitter.language.add('borklang')"))
eq(
false,
exec_lua("return pcall(vim.treesitter.language.add, 'borklang', { path = 'borkbork.so' })")
)
- eq(
- ".../language.lua:0: no parser for 'borklang' language, see :help treesitter-parsers",
- pcall_err(exec_lua, "parser = vim.treesitter.language.inspect('borklang')")
- )
-
matches(
'Failed to load parser: uv_dlsym: .+',
pcall_err(exec_lua, 'vim.treesitter.language.add("c", { symbol_name = "borklang" })')
)
end)
- it('shows error for invalid language name', function()
- eq(
- ".../language.lua:0: '/foo/' is not a valid language name",
- pcall_err(exec_lua, 'vim.treesitter.language.add("/foo/")')
- )
+ it('does not load parser for invalid language name', function()
+ eq(NIL, exec_lua('vim.treesitter.language.add("/foo/")'))
end)
it('inspects language', function()
- local keys, fields, symbols = unpack(exec_lua([[
+ local keys, fields, symbols = unpack(exec_lua(function()
local lang = vim.treesitter.language.inspect('c')
local keys, symbols = {}, {}
- for k,_ in pairs(lang) do
- keys[k] = true
+ for k, v in pairs(lang) do
+ if type(v) == 'boolean' then
+ keys[k] = v
+ else
+ keys[k] = true
+ end
end
-- symbols array can have "holes" and is thus not a valid msgpack array
@@ -66,10 +65,10 @@ describe('treesitter language API', function()
for _, v in pairs(lang.symbols) do
table.insert(symbols, v)
end
- return {keys, lang.fields, symbols}
- ]]))
+ return { keys, lang.fields, symbols }
+ end))
- eq({ fields = true, symbols = true, _abi_version = true }, keys)
+ eq({ fields = true, symbols = true, _abi_version = true, _wasm = false }, keys)
local fset = {}
for _, f in pairs(fields) do
@@ -101,9 +100,10 @@ describe('treesitter language API', function()
command('set filetype=borklang')
-- Should throw an error when filetype changes to borklang
eq(
- ".../language.lua:0: no parser for 'borklang' language, see :help treesitter-parsers",
+ '.../treesitter.lua:0: Parser could not be created for buffer 1 and language "borklang"',
pcall_err(exec_lua, "new_parser = vim.treesitter.get_parser(0, 'borklang')")
)
+ eq(NIL, exec_lua("return vim.treesitter.get_parser(0, 'borklang', { error = false })"))
end
)
@@ -113,12 +113,14 @@ describe('treesitter language API', function()
int x = 3;
}]])
- exec_lua([[
- langtree = vim.treesitter.get_parser(0, "c")
- tree = langtree:tree_for_range({1, 3, 1, 3})
- ]])
-
- eq('<node translation_unit>', exec_lua('return tostring(tree:root())'))
+ eq(
+ '<node translation_unit>',
+ exec_lua(function()
+ local langtree = vim.treesitter.get_parser(0, 'c')
+ local tree = langtree:tree_for_range({ 1, 3, 1, 3 })
+ return tostring(tree:root())
+ end)
+ )
end)
it('retrieve the tree given a range when range is out of bounds relative to buffer', function()
@@ -127,12 +129,14 @@ describe('treesitter language API', function()
int x = 3;
}]])
- exec_lua([[
- langtree = vim.treesitter.get_parser(0, "c")
- tree = langtree:tree_for_range({10, 10, 10, 10})
- ]])
-
- eq('<node translation_unit>', exec_lua('return tostring(tree:root())'))
+ eq(
+ '<node translation_unit>',
+ exec_lua(function()
+ local langtree = vim.treesitter.get_parser(0, 'c')
+ local tree = langtree:tree_for_range({ 10, 10, 10, 10 })
+ return tostring(tree:root())
+ end)
+ )
end)
it('retrieve the node given a range', function()
@@ -141,11 +145,24 @@ describe('treesitter language API', function()
int x = 3;
}]])
- exec_lua([[
- langtree = vim.treesitter.get_parser(0, "c")
- node = langtree:named_node_for_range({1, 3, 1, 3})
- ]])
+ eq(
+ '<node primitive_type>',
+ exec_lua(function()
+ local langtree = vim.treesitter.get_parser(0, 'c')
+ local node = langtree:named_node_for_range({ 1, 3, 1, 3 })
+ return tostring(node)
+ end)
+ )
+ end)
+
+ it('retrieve an anonymous node given a range', function()
+ insert([[vim.fn.input()]])
+
+ exec_lua(function()
+ _G.langtree = vim.treesitter.get_parser(0, 'lua')
+ _G.node = _G.langtree:node_for_range({ 0, 3, 0, 3 })
+ end)
- eq('<node primitive_type>', exec_lua('return tostring(node)'))
+ eq('.', exec_lua('return node:type()'))
end)
end)
diff --git a/test/functional/treesitter/node_spec.lua b/test/functional/treesitter/node_spec.lua
index 96579f296b..d07ed35368 100644
--- a/test/functional/treesitter/node_spec.lua
+++ b/test/functional/treesitter/node_spec.lua
@@ -18,43 +18,60 @@ describe('treesitter node API', function()
it('double free tree', function()
insert('F')
- exec_lua([[
+ exec_lua(function()
vim.treesitter.start(0, 'lua')
vim.treesitter.get_node():tree()
vim.treesitter.get_node():tree()
collectgarbage()
- ]])
+ end)
assert_alive()
end)
it('double free tree 2', function()
- exec_lua([[
- parser = vim.treesitter.get_parser(0, "c")
+ exec_lua(function()
+ local parser = vim.treesitter.get_parser(0, 'c')
local x = parser:parse()[1]:root():tree()
- vim.api.nvim_buf_set_text(0, 0,0, 0,0, {'y'})
+ vim.api.nvim_buf_set_text(0, 0, 0, 0, 0, { 'y' })
parser:parse()
- vim.api.nvim_buf_set_text(0, 0,0, 0,1, {'z'})
+ vim.api.nvim_buf_set_text(0, 0, 0, 0, 1, { 'z' })
parser:parse()
collectgarbage()
x:root()
- ]])
+ end)
assert_alive()
end)
it('get_node() with lang given', function()
-- this buffer doesn't have filetype set!
insert('local foo = function() end')
- exec_lua([[
- node = vim.treesitter.get_node({
+ exec_lua(function()
+ _G.node = vim.treesitter.get_node({
bufnr = 0,
- pos = { 0, 6 }, -- on "foo"
+ pos = { 0, 6 }, -- on "foo"
lang = 'lua',
})
- ]])
+ end)
eq('foo', lua_eval('vim.treesitter.get_node_text(node, 0)'))
eq('identifier', lua_eval('node:type()'))
end)
+ it('get_node() with anonymous nodes included', function()
+ insert([[print('test')]])
+
+ exec_lua(function()
+ _G.parser = vim.treesitter.get_parser(0, 'lua')
+ _G.tree = _G.parser:parse()[1]
+ _G.node = vim.treesitter.get_node({
+ bufnr = 0,
+ pos = { 0, 6 }, -- on the first apostrophe
+ include_anonymous = true,
+ })
+ end)
+
+ eq("'", lua_eval('node:type()'))
+ eq(false, lua_eval('node:named()'))
+ end)
+
it('can move between siblings', function()
insert([[
int main(int x, int y, int z) {
@@ -62,16 +79,16 @@ describe('treesitter node API', function()
}
]])
- exec_lua([[
- parser = vim.treesitter.get_parser(0, "c")
- tree = parser:parse()[1]
- root = tree:root()
- lang = vim.treesitter.language.inspect('c')
+ exec_lua(function()
+ local parser = vim.treesitter.get_parser(0, 'c')
+ local tree = parser:parse()[1]
+ _G.root = tree:root()
+ vim.treesitter.language.inspect('c')
- function node_text(node)
+ function _G.node_text(node)
return vim.treesitter.get_node_text(node, 0)
end
- ]])
+ end)
exec_lua 'node = root:descendant_for_range(0, 11, 0, 16)'
eq('int x', lua_eval('node_text(node)'))
@@ -101,13 +118,13 @@ describe('treesitter node API', function()
int x = 3;
}]])
- local len = exec_lua([[
- tree = vim.treesitter.get_parser(0, "c"):parse()[1]
- node = tree:root():child(0)
- children = node:named_children()
+ local len = exec_lua(function()
+ local tree = vim.treesitter.get_parser(0, 'c'):parse()[1]
+ local node = assert(tree:root():child(0))
+ _G.children = node:named_children()
- return #children
- ]])
+ return #_G.children
+ end)
eq(3, len)
eq('<node compound_statement>', lua_eval('tostring(children[3])'))
@@ -119,11 +136,11 @@ describe('treesitter node API', function()
int x = 3;
}]])
- exec_lua([[
- tree = vim.treesitter.get_parser(0, "c"):parse()[1]
- root = tree:root()
- node = root:child(0):child(2)
- ]])
+ exec_lua(function()
+ local tree = vim.treesitter.get_parser(0, 'c'):parse()[1]
+ _G.root = tree:root()
+ _G.node = _G.root:child(0):child(2)
+ end)
eq(lua_eval('tostring(root)'), lua_eval('tostring(node:root())'))
end)
@@ -134,11 +151,11 @@ describe('treesitter node API', function()
int x = 3;
}]])
- exec_lua([[
- tree = vim.treesitter.get_parser(0, "c"):parse()[1]
- root = tree:root()
- child = root:child(0):child(0)
- ]])
+ exec_lua(function()
+ local tree = vim.treesitter.get_parser(0, 'c'):parse()[1]
+ _G.root = tree:root()
+ _G.child = _G.root:child(0):child(0)
+ end)
eq(28, lua_eval('root:byte_length()'))
eq(3, lua_eval('child:byte_length()'))
@@ -150,15 +167,15 @@ describe('treesitter node API', function()
int x = 3;
}]])
- exec_lua([[
- tree = vim.treesitter.get_parser(0, "c"):parse()[1]
- root = tree:root()
- main = root:child(0)
- body = main:child(2)
- statement = body:child(1)
- declarator = statement:child(1)
- value = declarator:child(1)
- ]])
+ exec_lua(function()
+ local tree = vim.treesitter.get_parser(0, 'c'):parse()[1]
+ _G.root = tree:root()
+ _G.main = _G.root:child(0)
+ _G.body = _G.main:child(2)
+ _G.statement = _G.body:child(1)
+ _G.declarator = _G.statement:child(1)
+ _G.value = _G.declarator:child(1)
+ end)
eq(lua_eval('main:type()'), lua_eval('root:child_containing_descendant(value):type()'))
eq(lua_eval('body:type()'), lua_eval('main:child_containing_descendant(value):type()'))
diff --git a/test/functional/treesitter/parser_spec.lua b/test/functional/treesitter/parser_spec.lua
index dbd6bb3c23..c8829f4785 100644
--- a/test/functional/treesitter/parser_spec.lua
+++ b/test/functional/treesitter/parser_spec.lua
@@ -12,9 +12,9 @@ local feed = n.feed
describe('treesitter parser API', function()
before_each(function()
clear()
- exec_lua [[
+ exec_lua(function()
vim.g.__ts_debug = 1
- ]]
+ end)
end)
it('parses buffer', function()
@@ -23,12 +23,12 @@ describe('treesitter parser API', function()
int x = 3;
}]])
- exec_lua([[
- parser = vim.treesitter.get_parser(0, "c")
- tree = parser:parse()[1]
- root = tree:root()
- lang = vim.treesitter.language.inspect('c')
- ]])
+ exec_lua(function()
+ _G.parser = vim.treesitter.get_parser(0, 'c')
+ _G.tree = _G.parser:parse()[1]
+ _G.root = _G.tree:root()
+ _G.lang = vim.treesitter.language.inspect('c')
+ end)
eq('<tree>', exec_lua('return tostring(tree)'))
eq('<node translation_unit>', exec_lua('return tostring(root)'))
@@ -59,11 +59,11 @@ describe('treesitter parser API', function()
)
feed('2G7|ay')
- exec_lua([[
- tree2 = parser:parse()[1]
- root2 = tree2:root()
- descendant2 = root2:descendant_for_range(1,2,1,13)
- ]])
+ exec_lua(function()
+ _G.tree2 = _G.parser:parse()[1]
+ _G.root2 = _G.tree2:root()
+ _G.descendant2 = _G.root2:descendant_for_range(1, 2, 1, 13)
+ end)
eq(false, exec_lua('return tree2 == tree1'))
eq(false, exec_lua('return root2 == root'))
eq('<node declaration>', exec_lua('return tostring(descendant2)'))
@@ -112,17 +112,17 @@ void ui_refresh(void)
it('allows to iterate over nodes children', function()
insert(test_text)
- local res = exec_lua([[
- parser = vim.treesitter.get_parser(0, "c")
+ local res = exec_lua(function()
+ local parser = vim.treesitter.get_parser(0, 'c')
- func_node = parser:parse()[1]:root():child(0)
+ local func_node = parser:parse()[1]:root():child(0)
- res = {}
+ local res = {}
for node, field in func_node:iter_children() do
table.insert(res, { node:type(), field })
end
return res
- ]])
+ end)
eq({
{ 'primitive_type', 'type' },
@@ -135,9 +135,7 @@ void ui_refresh(void)
insert(test_text)
eq(
- '.../treesitter.lua:0: There is no parser available for buffer 1 and one'
- .. ' could not be created because lang could not be determined. Either'
- .. ' pass lang or set the buffer filetype',
+ '.../treesitter.lua:0: Parser not found for buffer 1: language could not be determined',
pcall_err(exec_lua, 'vim.treesitter.get_parser(0)')
)
@@ -148,43 +146,43 @@ void ui_refresh(void)
it('allows to get a child by field', function()
insert(test_text)
- local res = exec_lua([[
- parser = vim.treesitter.get_parser(0, "c")
+ local res = exec_lua(function()
+ local parser = vim.treesitter.get_parser(0, 'c')
- func_node = parser:parse()[1]:root():child(0)
+ _G.func_node = parser:parse()[1]:root():child(0)
local res = {}
- for _, node in ipairs(func_node:field("type")) do
+ for _, node in ipairs(_G.func_node:field('type')) do
table.insert(res, { node:type(), node:range() })
end
return res
- ]])
+ end)
eq({ { 'primitive_type', 0, 0, 0, 4 } }, res)
- local res_fail = exec_lua([[
- parser = vim.treesitter.get_parser(0, "c")
+ local res_fail = exec_lua(function()
+ vim.treesitter.get_parser(0, 'c')
- return #func_node:field("foo") == 0
- ]])
+ return #_G.func_node:field('foo') == 0
+ end)
assert(res_fail)
end)
it('supports getting text of multiline node', function()
insert(test_text)
- local res = exec_lua([[
- local parser = vim.treesitter.get_parser(0, "c")
+ local res = exec_lua(function()
+ local parser = vim.treesitter.get_parser(0, 'c')
local tree = parser:parse()[1]
return vim.treesitter.get_node_text(tree:root(), 0)
- ]])
+ end)
eq(test_text, res)
- local res2 = exec_lua([[
- local parser = vim.treesitter.get_parser(0, "c")
+ local res2 = exec_lua(function()
+ local parser = vim.treesitter.get_parser(0, 'c')
local root = parser:parse()[1]:root()
return vim.treesitter.get_node_text(root:child(0):child(0), 0)
- ]])
+ end)
eq('void', res2)
end)
@@ -196,7 +194,7 @@ end]]
insert(text)
eq(
'',
- exec_lua [[
+ exec_lua(function()
local fake_node = {}
function fake_node:start()
return 3, 0, 23
@@ -211,7 +209,7 @@ end]]
return 3, 0, 3, 0
end
return vim.treesitter.get_node_text(fake_node, 0)
- ]]
+ end)
)
end)
@@ -221,7 +219,7 @@ end]]
{}
```]]
insert(text)
- local result = exec_lua([[
+ local result = exec_lua(function()
local fake_node = {}
function fake_node:start()
return 1, 0, 7
@@ -233,38 +231,38 @@ end]]
return 1, 0, 1, 0
end
return vim.treesitter.get_node_text(fake_node, 0) == ''
- ]])
+ end)
eq(true, result)
end)
it('allows to set simple ranges', function()
insert(test_text)
- local res = exec_lua [[
- parser = vim.treesitter.get_parser(0, "c")
- return { parser:parse()[1]:root():range() }
- ]]
+ local res = exec_lua(function()
+ _G.parser = vim.treesitter.get_parser(0, 'c')
+ return { _G.parser:parse()[1]:root():range() }
+ end)
eq({ 0, 0, 19, 0 }, res)
-- The following sets the included ranges for the current parser
-- As stated here, this only includes the function (thus the whole buffer, without the last line)
- local res2 = exec_lua [[
- local root = parser:parse()[1]:root()
- parser:set_included_regions({{root:child(0)}})
- parser:invalidate()
- return { parser:parse(true)[1]:root():range() }
- ]]
+ local res2 = exec_lua(function()
+ local root = _G.parser:parse()[1]:root()
+ _G.parser:set_included_regions({ { root:child(0) } })
+ _G.parser:invalidate()
+ return { _G.parser:parse(true)[1]:root():range() }
+ end)
eq({ 0, 0, 18, 1 }, res2)
eq({ { { 0, 0, 0, 18, 1, 512 } } }, exec_lua [[ return parser:included_regions() ]])
- local range_tbl = exec_lua [[
- parser:set_included_regions { { { 0, 0, 17, 1 } } }
- parser:parse()
- return parser:included_regions()
- ]]
+ local range_tbl = exec_lua(function()
+ _G.parser:set_included_regions { { { 0, 0, 17, 1 } } }
+ _G.parser:parse()
+ return _G.parser:included_regions()
+ end)
eq({ { { 0, 0, 0, 17, 1, 508 } } }, range_tbl)
end)
@@ -272,25 +270,25 @@ end]]
it('allows to set complex ranges', function()
insert(test_text)
- local res = exec_lua [[
- parser = vim.treesitter.get_parser(0, "c")
- query = vim.treesitter.query.parse("c", "(declaration) @decl")
+ local res = exec_lua(function()
+ local parser = vim.treesitter.get_parser(0, 'c')
+ local query = vim.treesitter.query.parse('c', '(declaration) @decl')
- local nodes = {}
- for _, node in query:iter_captures(parser:parse()[1]:root(), 0) do
- table.insert(nodes, node)
- end
+ local nodes = {}
+ for _, node in query:iter_captures(parser:parse()[1]:root(), 0) do
+ table.insert(nodes, node)
+ end
- parser:set_included_regions({nodes})
+ parser:set_included_regions({ nodes })
- local root = parser:parse(true)[1]:root()
+ local root = parser:parse(true)[1]:root()
- local res = {}
- for i=0,(root:named_child_count() - 1) do
- table.insert(res, { root:named_child(i):range() })
- end
- return res
- ]]
+ local res = {}
+ for i = 0, (root:named_child_count() - 1) do
+ table.insert(res, { root:named_child(i):range() })
+ end
+ return res
+ end)
eq({
{ 2, 2, 2, 40 },
@@ -304,10 +302,10 @@ end]]
end)
it('allows to create string parsers', function()
- local ret = exec_lua [[
- local parser = vim.treesitter.get_string_parser("int foo = 42;", "c")
+ local ret = exec_lua(function()
+ local parser = vim.treesitter.get_string_parser('int foo = 42;', 'c')
return { parser:parse()[1]:root():range() }
- ]]
+ end)
eq({ 0, 0, 0, 13 }, ret)
end)
@@ -318,33 +316,31 @@ end]]
int bar = 13;
]]
- local ret = exec_lua(
- [[
- local str = ...
- local parser = vim.treesitter.get_string_parser(str, "c")
+ local ret = exec_lua(function(str)
+ local parser = vim.treesitter.get_string_parser(str, 'c')
- local nodes = {}
- local query = vim.treesitter.query.parse("c", '((identifier) @id (#eq? @id "foo"))')
+ local nodes = {}
+ local query = vim.treesitter.query.parse('c', '((identifier) @id (#eq? @id "foo"))')
- for _, node in query:iter_captures(parser:parse()[1]:root(), str) do
- table.insert(nodes, { node:range() })
- end
+ for _, node in query:iter_captures(parser:parse()[1]:root(), str) do
+ table.insert(nodes, { node:range() })
+ end
- return nodes
- ]],
- txt
- )
+ return nodes
+ end, txt)
eq({ { 0, 10, 0, 13 } }, ret)
end)
describe('when creating a language tree', function()
local function get_ranges()
- return exec_lua [[
+ return exec_lua(function()
local result = {}
- parser:for_each_tree(function(tree) table.insert(result, {tree:root():range()}) end)
+ _G.parser:for_each_tree(function(tree)
+ table.insert(result, { tree:root():range() })
+ end)
return result
- ]]
+ end)
end
before_each(function()
@@ -360,16 +356,17 @@ int x = INT_MAX;
describe('when parsing regions independently', function()
it('should inject a language', function()
- exec_lua([[
- parser = vim.treesitter.get_parser(0, "c", {
+ exec_lua(function()
+ _G.parser = vim.treesitter.get_parser(0, 'c', {
injections = {
c = (
- '(preproc_def (preproc_arg) @injection.content (#set! injection.language "c")) ' ..
- '(preproc_function_def value: (preproc_arg) @injection.content (#set! injection.language "c"))'
- )
- }})
- parser:parse(true)
- ]])
+ '(preproc_def (preproc_arg) @injection.content (#set! injection.language "c")) '
+ .. '(preproc_function_def value: (preproc_arg) @injection.content (#set! injection.language "c"))'
+ ),
+ },
+ })
+ _G.parser:parse(true)
+ end)
eq('table', exec_lua('return type(parser:children().c)'))
eq(5, exec_lua('return #parser:children().c:trees()'))
@@ -397,16 +394,17 @@ int x = INT_MAX;
describe('when parsing regions combined', function()
it('should inject a language', function()
- exec_lua([[
- parser = vim.treesitter.get_parser(0, "c", {
+ exec_lua(function()
+ _G.parser = vim.treesitter.get_parser(0, 'c', {
injections = {
c = (
- '(preproc_def (preproc_arg) @injection.content (#set! injection.language "c") (#set! injection.combined)) ' ..
- '(preproc_function_def value: (preproc_arg) @injection.content (#set! injection.language "c") (#set! injection.combined))'
- )
- }})
- parser:parse(true)
- ]])
+ '(preproc_def (preproc_arg) @injection.content (#set! injection.language "c") (#set! injection.combined)) '
+ .. '(preproc_function_def value: (preproc_arg) @injection.content (#set! injection.language "c") (#set! injection.combined))'
+ ),
+ },
+ })
+ _G.parser:parse(true)
+ end)
eq('table', exec_lua('return type(parser:children().c)'))
eq(2, exec_lua('return #parser:children().c:trees()'))
@@ -447,16 +445,17 @@ int x = INT_MAX;
describe('when using injection.self', function()
it('should inject the source language', function()
- exec_lua([[
- parser = vim.treesitter.get_parser(0, "c", {
+ exec_lua(function()
+ _G.parser = vim.treesitter.get_parser(0, 'c', {
injections = {
c = (
- '(preproc_def (preproc_arg) @injection.content (#set! injection.self)) ' ..
- '(preproc_function_def value: (preproc_arg) @injection.content (#set! injection.self))'
- )
- }})
- parser:parse(true)
- ]])
+ '(preproc_def (preproc_arg) @injection.content (#set! injection.self)) '
+ .. '(preproc_function_def value: (preproc_arg) @injection.content (#set! injection.self))'
+ ),
+ },
+ })
+ _G.parser:parse(true)
+ end)
eq('table', exec_lua('return type(parser:children().c)'))
eq(5, exec_lua('return #parser:children().c:trees()'))
@@ -484,16 +483,17 @@ int x = INT_MAX;
describe('when using the offset directive', function()
it('should shift the range by the directive amount', function()
- exec_lua([[
- parser = vim.treesitter.get_parser(0, "c", {
+ exec_lua(function()
+ _G.parser = vim.treesitter.get_parser(0, 'c', {
injections = {
c = (
- '(preproc_def ((preproc_arg) @injection.content (#set! injection.language "c") (#offset! @injection.content 0 2 0 -1))) ' ..
- '(preproc_function_def value: (preproc_arg) @injection.content (#set! injection.language "c"))'
- )
- }})
- parser:parse(true)
- ]])
+ '(preproc_def ((preproc_arg) @injection.content (#set! injection.language "c") (#offset! @injection.content 0 2 0 -1))) '
+ .. '(preproc_function_def value: (preproc_arg) @injection.content (#set! injection.language "c"))'
+ ),
+ },
+ })
+ _G.parser:parse(true)
+ end)
eq('table', exec_lua('return type(parser:children().c)'))
eq({
@@ -506,7 +506,7 @@ int x = INT_MAX;
}, get_ranges())
end)
it('should list all directives', function()
- local res_list = exec_lua [[
+ local res_list = exec_lua(function()
local query = vim.treesitter.query
local list = query.list_directives()
@@ -514,7 +514,7 @@ int x = INT_MAX;
table.sort(list)
return list
- ]]
+ end)
eq({ 'gsub!', 'offset!', 'set!', 'trim!' }, res_list)
end)
@@ -530,18 +530,18 @@ int x = INT_MAX;
end)
it('should return the correct language tree', function()
- local result = exec_lua([[
- parser = vim.treesitter.get_parser(0, "c", {
+ local result = exec_lua(function()
+ local parser = vim.treesitter.get_parser(0, 'c', {
injections = {
- c = '(preproc_def (preproc_arg) @injection.content (#set! injection.language "c"))'
- }
+ c = '(preproc_def (preproc_arg) @injection.content (#set! injection.language "c"))',
+ },
})
parser:parse(true)
- local sub_tree = parser:language_for_range({1, 18, 1, 19})
+ local sub_tree = parser:language_for_range({ 1, 18, 1, 19 })
return sub_tree == parser:children().c
- ]])
+ end)
eq(true, result)
end)
@@ -555,23 +555,23 @@ print()
end)
it('ignores optional captures #23100', function()
- local result = exec_lua([[
- parser = vim.treesitter.get_parser(0, "lua", {
+ local result = exec_lua(function()
+ local parser = vim.treesitter.get_parser(0, 'lua', {
injections = {
lua = (
- '(function_call ' ..
- '(arguments ' ..
- '(string)? @injection.content ' ..
- '(number)? @injection.content ' ..
- '(#offset! @injection.content 0 1 0 -1) ' ..
- '(#set! injection.language "c")))'
- )
- }
+ '(function_call '
+ .. '(arguments '
+ .. '(string)? @injection.content '
+ .. '(number)? @injection.content '
+ .. '(#offset! @injection.content 0 1 0 -1) '
+ .. '(#set! injection.language "c")))'
+ ),
+ },
})
parser:parse(true)
return parser:is_valid()
- ]])
+ end)
eq(true, result)
end)
@@ -584,18 +584,14 @@ print()
int x = 3;
]])
- local result = exec_lua([[
- local result
-
- query = vim.treesitter.query.parse("c", '((number_literal) @number (#set! "key" "value"))')
- parser = vim.treesitter.get_parser(0, "c")
-
- for pattern, match, metadata in query:iter_matches(parser:parse()[1]:root(), 0, 0, -1, { all = true }) do
- result = metadata.key
- end
+ local result = exec_lua(function()
+ local query =
+ vim.treesitter.query.parse('c', '((number_literal) @number (#set! "key" "value"))')
+ local parser = vim.treesitter.get_parser(0, 'c')
- return result
- ]])
+ local _, _, metadata = query:iter_matches(parser:parse()[1]:root(), 0, 0, -1)()
+ return metadata.key
+ end)
eq('value', result)
end)
@@ -606,19 +602,17 @@ print()
int x = 3;
]])
- local result = exec_lua([[
- local query = vim.treesitter.query
- local value
+ local result = exec_lua(function()
+ local query = vim.treesitter.query.parse(
+ 'c',
+ '((number_literal) @number (#set! @number "key" "value"))'
+ )
+ local parser = vim.treesitter.get_parser(0, 'c')
- query = vim.treesitter.query.parse("c", '((number_literal) @number (#set! @number "key" "value"))')
- parser = vim.treesitter.get_parser(0, "c")
-
- for pattern, match, metadata in query:iter_matches(parser:parse()[1]:root(), 0, 0, -1, { all = true }) do
- for _, nested_tbl in pairs(metadata) do
- return nested_tbl.key
- end
- end
- ]])
+ local _, _, metadata = query:iter_matches(parser:parse()[1]:root(), 0, 0, -1)()
+ local _, nested_tbl = next(metadata)
+ return nested_tbl.key
+ end)
eq('value', result)
end)
@@ -628,19 +622,17 @@ print()
int x = 3;
]])
- local result = exec_lua([[
- local query = vim.treesitter.query
- local result
-
- query = vim.treesitter.query.parse("c", '((number_literal) @number (#set! @number "key" "value") (#set! @number "key2" "value2"))')
- parser = vim.treesitter.get_parser(0, "c")
+ local result = exec_lua(function()
+ local query = vim.treesitter.query.parse(
+ 'c',
+ '((number_literal) @number (#set! @number "key" "value") (#set! @number "key2" "value2"))'
+ )
+ local parser = vim.treesitter.get_parser(0, 'c')
- for pattern, match, metadata in query:iter_matches(parser:parse()[1]:root(), 0, 0, -1, { all = true }) do
- for _, nested_tbl in pairs(metadata) do
- return nested_tbl
- end
- end
- ]])
+ local _, _, metadata = query:iter_matches(parser:parse()[1]:root(), 0, 0, -1)()
+ local _, nested_tbl = next(metadata)
+ return nested_tbl
+ end)
local expected = {
['key'] = 'value',
['key2'] = 'value2',
@@ -663,24 +655,21 @@ print()
(function_definition) @function
]]
- exec_lua([[
+ exec_lua(function()
vim.treesitter.start(0, 'c')
- ]])
+ end)
local function run_query()
- return exec_lua(
- [[
- local query = vim.treesitter.query.parse("c", ...)
- parser = vim.treesitter.get_parser()
- tree = parser:parse()[1]
- res = {}
- for id, node in query:iter_captures(tree:root()) do
- table.insert(res, {query.captures[id], node:range()})
- end
- return res
- ]],
- query0
- )
+ return exec_lua(function()
+ local query = vim.treesitter.query.parse('c', query0)
+ local parser = vim.treesitter.get_parser()
+ local tree = parser:parse()[1]
+ local res = {}
+ for id, node in query:iter_captures(tree:root()) do
+ table.insert(res, { query.captures[id], node:range() })
+ end
+ return res
+ end)
end
eq({
@@ -718,18 +707,15 @@ print()
]]
]==]
- local r = exec_lua(
- [[
- local parser = vim.treesitter.get_string_parser(..., 'lua')
- parser:parse(true)
- local ranges = {}
- parser:for_each_tree(function(tstree, tree)
- ranges[tree:lang()] = { tstree:root():range(true) }
- end)
- return ranges
- ]],
- source
- )
+ local r = exec_lua(function()
+ local parser = vim.treesitter.get_string_parser(source, 'lua')
+ parser:parse(true)
+ local ranges = {}
+ parser:for_each_tree(function(tstree, tree)
+ ranges[tree:lang()] = { tstree:root():range(true) }
+ end)
+ return ranges
+ end)
eq({
lua = { 0, 6, 6, 16, 4, 438 },
@@ -741,19 +727,14 @@ print()
-- the ranges but only provide a Range4. Strip the byte entries from the ranges and make sure
-- add_bytes() produces the same result.
- local rb = exec_lua(
- [[
- local r, source = ...
- local add_bytes = require('vim.treesitter._range').add_bytes
- for lang, range in pairs(r) do
- r[lang] = {range[1], range[2], range[4], range[5]}
- r[lang] = add_bytes(source, r[lang])
- end
- return r
- ]],
- r,
- source
- )
+ local rb = exec_lua(function()
+ local add_bytes = require('vim.treesitter._range').add_bytes
+ for lang, range in pairs(r) do
+ r[lang] = { range[1], range[2], range[4], range[5] }
+ r[lang] = add_bytes(source, r[lang])
+ end
+ return r
+ end)
eq(rb, r)
end)
@@ -766,25 +747,25 @@ print()
]]
-- This is not a valid injection since (code) has children and include-children is not set
- exec_lua [[
- parser1 = require('vim.treesitter.languagetree').new(0, "vimdoc", {
+ exec_lua(function()
+ _G.parser1 = require('vim.treesitter.languagetree').new(0, 'vimdoc', {
injections = {
- vimdoc = "((codeblock (language) @injection.language (code) @injection.content))"
- }
+ vimdoc = '((codeblock (language) @injection.language (code) @injection.content))',
+ },
})
- parser1:parse(true)
- ]]
+ _G.parser1:parse(true)
+ end)
eq(0, exec_lua('return #vim.tbl_keys(parser1:children())'))
- exec_lua [[
- parser2 = require('vim.treesitter.languagetree').new(0, "vimdoc", {
+ exec_lua(function()
+ _G.parser2 = require('vim.treesitter.languagetree').new(0, 'vimdoc', {
injections = {
- vimdoc = "((codeblock (language) @injection.language (code) @injection.content) (#set! injection.include-children))"
- }
+ vimdoc = '((codeblock (language) @injection.language (code) @injection.content) (#set! injection.include-children))',
+ },
})
- parser2:parse(true)
- ]]
+ _G.parser2:parse(true)
+ end)
eq(1, exec_lua('return #vim.tbl_keys(parser2:children())'))
eq({ { { 1, 0, 21, 2, 0, 42 } } }, exec_lua('return parser2:children().lua:included_regions()'))
@@ -821,46 +802,46 @@ print()
<
]])
- exec_lua [[
- parser = require('vim.treesitter.languagetree').new(0, "vimdoc", {
+ exec_lua(function()
+ _G.parser = require('vim.treesitter.languagetree').new(0, 'vimdoc', {
injections = {
- vimdoc = "((codeblock (language) @injection.language (code) @injection.content) (#set! injection.include-children))"
- }
+ vimdoc = '((codeblock (language) @injection.language (code) @injection.content) (#set! injection.include-children))',
+ },
})
- ]]
+ end)
--- Do not parse injections by default
eq(
0,
- exec_lua [[
- parser:parse()
- return #vim.tbl_keys(parser:children())
- ]]
+ exec_lua(function()
+ _G.parser:parse()
+ return #vim.tbl_keys(_G.parser:children())
+ end)
)
--- Only parse injections between lines 0, 2
eq(
1,
- exec_lua [[
- parser:parse({0, 2})
- return #parser:children().lua:trees()
- ]]
+ exec_lua(function()
+ _G.parser:parse({ 0, 2 })
+ return #_G.parser:children().lua:trees()
+ end)
)
eq(
2,
- exec_lua [[
- parser:parse({2, 6})
- return #parser:children().lua:trees()
- ]]
+ exec_lua(function()
+ _G.parser:parse({ 2, 6 })
+ return #_G.parser:children().lua:trees()
+ end)
)
eq(
7,
- exec_lua [[
- parser:parse(true)
- return #parser:children().lua:trees()
- ]]
+ exec_lua(function()
+ _G.parser:parse(true)
+ return #_G.parser:children().lua:trees()
+ end)
)
end)
@@ -876,13 +857,13 @@ print()
feed(':set ft=help<cr>')
- exec_lua [[
- vim.treesitter.get_parser(0, "vimdoc", {
+ exec_lua(function()
+ vim.treesitter.get_parser(0, 'vimdoc', {
injections = {
- vimdoc = "((codeblock (language) @injection.language (code) @injection.content) (#set! injection.include-children))"
- }
+ vimdoc = '((codeblock (language) @injection.language (code) @injection.content) (#set! injection.include-children))',
+ },
})
- ]]
+ end)
end)
it('is valid excluding, invalid including children initially', function()
diff --git a/test/functional/treesitter/query_spec.lua b/test/functional/treesitter/query_spec.lua
index c3a376cd71..c97619c913 100644
--- a/test/functional/treesitter/query_spec.lua
+++ b/test/functional/treesitter/query_spec.lua
@@ -10,28 +10,26 @@ local pcall_err = t.pcall_err
local api = n.api
local fn = n.fn
-local get_query_result_code = [[
- function get_query_result(query_text)
- cquery = vim.treesitter.query.parse("c", query_text)
- parser = vim.treesitter.get_parser(0, "c")
- tree = parser:parse()[1]
- res = {}
- for cid, node in cquery:iter_captures(tree:root(), 0) do
- -- can't transmit node over RPC. just check the name, range, and text
- local text = vim.treesitter.get_node_text(node, 0)
- local range = {node:range()}
- table.insert(res, { cquery.captures[cid], node:type(), range, text })
- end
- return res
+local function get_query_result(query_text)
+ local cquery = vim.treesitter.query.parse('c', query_text)
+ local parser = vim.treesitter.get_parser(0, 'c')
+ local tree = parser:parse()[1]
+ local res = {}
+ for cid, node in cquery:iter_captures(tree:root(), 0) do
+ -- can't transmit node over RPC. just check the name, range, and text
+ local text = vim.treesitter.get_node_text(node, 0)
+ local range = { node:range() }
+ table.insert(res, { cquery.captures[cid], node:type(), range, text })
end
-]]
+ return res
+end
describe('treesitter query API', function()
before_each(function()
clear()
- exec_lua [[
+ exec_lua(function()
vim.g.__ts_debug = 1
- ]]
+ end)
end)
local test_text = [[
@@ -71,9 +69,9 @@ void ui_refresh(void)
it('supports runtime queries', function()
---@type string[]
- local ret = exec_lua [[
- return vim.treesitter.query.get("c", "highlights").captures
- ]]
+ local ret = exec_lua(function()
+ return vim.treesitter.query.get('c', 'highlights').captures
+ end)
-- see $VIMRUNTIME/queries/c/highlights.scm
eq('variable', ret[1])
@@ -84,22 +82,17 @@ void ui_refresh(void)
local long_query = test_query:rep(100)
---@return number
local function q(_n)
- return exec_lua(
- [[
- local query, n = ...
- local before = vim.api.nvim__stats().ts_query_parse_count
- collectgarbage("stop")
- for i=1, n, 1 do
- cquery = vim.treesitter.query.parse("c", ...)
- end
- collectgarbage("restart")
- collectgarbage("collect")
- local after = vim.api.nvim__stats().ts_query_parse_count
- return after - before
- ]],
- long_query,
- _n
- )
+ return exec_lua(function()
+ local before = vim.api.nvim__stats().ts_query_parse_count
+ collectgarbage('stop')
+ for _ = 1, _n, 1 do
+ vim.treesitter.query.parse('c', long_query, _n)
+ end
+ collectgarbage('restart')
+ collectgarbage('collect')
+ local after = vim.api.nvim__stats().ts_query_parse_count
+ return after - before
+ end)
end
eq(1, q(1))
@@ -110,20 +103,17 @@ void ui_refresh(void)
it('supports query and iter by capture (iter_captures)', function()
insert(test_text)
- local res = exec_lua(
- [[
- cquery = vim.treesitter.query.parse("c", ...)
- parser = vim.treesitter.get_parser(0, "c")
- tree = parser:parse()[1]
- res = {}
- for cid, node in cquery:iter_captures(tree:root(), 0, 7, 14) do
- -- can't transmit node over RPC. just check the name and range
- table.insert(res, { '@' .. cquery.captures[cid], node:type(), node:range() })
- end
- return res
- ]],
- test_query
- )
+ local res = exec_lua(function()
+ local cquery = vim.treesitter.query.parse('c', test_query)
+ local parser = vim.treesitter.get_parser(0, 'c')
+ local tree = parser:parse()[1]
+ local res = {}
+ for cid, node in cquery:iter_captures(tree:root(), 0, 7, 14) do
+ -- can't transmit node over RPC. just check the name and range
+ table.insert(res, { '@' .. cquery.captures[cid], node:type(), node:range() })
+ end
+ return res
+ end)
eq({
{ '@type', 'primitive_type', 8, 2, 8, 6 }, -- bool
@@ -143,26 +133,23 @@ void ui_refresh(void)
insert(test_text)
---@type table
- local res = exec_lua(
- [[
- cquery = vim.treesitter.query.parse("c", ...)
- parser = vim.treesitter.get_parser(0, "c")
- tree = parser:parse()[1]
- res = {}
- for pattern, match in cquery:iter_matches(tree:root(), 0, 7, 14, { all = true }) do
- -- can't transmit node over RPC. just check the name and range
- local mrepr = {}
- for cid, nodes in pairs(match) do
- for _, node in ipairs(nodes) do
- table.insert(mrepr, { '@' .. cquery.captures[cid], node:type(), node:range() })
- end
+ local res = exec_lua(function()
+ local cquery = vim.treesitter.query.parse('c', test_query)
+ local parser = vim.treesitter.get_parser(0, 'c')
+ local tree = parser:parse()[1]
+ local res = {}
+ for pattern, match in cquery:iter_matches(tree:root(), 0, 7, 14) do
+ -- can't transmit node over RPC. just check the name and range
+ local mrepr = {}
+ for cid, nodes in pairs(match) do
+ for _, node in ipairs(nodes) do
+ table.insert(mrepr, { '@' .. cquery.captures[cid], node:type(), node:range() })
end
- table.insert(res, { pattern, mrepr })
end
- return res
- ]],
- test_query
- )
+ table.insert(res, { pattern, mrepr })
+ end
+ return res
+ end)
eq({
{ 3, { { '@type', 'primitive_type', 8, 2, 8, 6 } } },
@@ -191,20 +178,20 @@ void ui_refresh(void)
it('supports query and iter by capture for quantifiers', function()
insert(test_text)
- local res = exec_lua(
- [[
- cquery = vim.treesitter.query.parse("c", ...)
- parser = vim.treesitter.get_parser(0, "c")
- tree = parser:parse()[1]
- res = {}
- for cid, node in cquery:iter_captures(tree:root(), 0, 7, 14) do
- -- can't transmit node over RPC. just check the name and range
- table.insert(res, { '@' .. cquery.captures[cid], node:type(), node:range() })
- end
- return res
- ]],
- '(expression_statement (assignment_expression (call_expression)))+ @funccall'
- )
+ local res = exec_lua(function()
+ local cquery = vim.treesitter.query.parse(
+ 'c',
+ '(expression_statement (assignment_expression (call_expression)))+ @funccall'
+ )
+ local parser = vim.treesitter.get_parser(0, 'c')
+ local tree = parser:parse()[1]
+ local res = {}
+ for cid, node in cquery:iter_captures(tree:root(), 0, 7, 14) do
+ -- can't transmit node over RPC. just check the name and range
+ table.insert(res, { '@' .. cquery.captures[cid], node:type(), node:range() })
+ end
+ return res
+ end)
eq({
{ '@funccall', 'expression_statement', 11, 4, 11, 34 },
@@ -216,26 +203,26 @@ void ui_refresh(void)
it('supports query and iter by match for quantifiers', function()
insert(test_text)
- local res = exec_lua(
- [[
- cquery = vim.treesitter.query.parse("c", ...)
- parser = vim.treesitter.get_parser(0, "c")
- tree = parser:parse()[1]
- res = {}
- for pattern, match in cquery:iter_matches(tree:root(), 0, 7, 14, { all = true }) do
- -- can't transmit node over RPC. just check the name and range
- local mrepr = {}
- for cid, nodes in pairs(match) do
- for _, node in ipairs(nodes) do
- table.insert(mrepr, { '@' .. cquery.captures[cid], node:type(), node:range() })
- end
+ local res = exec_lua(function()
+ local cquery = vim.treesitter.query.parse(
+ 'c',
+ '(expression_statement (assignment_expression (call_expression)))+ @funccall'
+ )
+ local parser = vim.treesitter.get_parser(0, 'c')
+ local tree = parser:parse()[1]
+ local res = {}
+ for pattern, match in cquery:iter_matches(tree:root(), 0, 7, 14) do
+ -- can't transmit node over RPC. just check the name and range
+ local mrepr = {}
+ for cid, nodes in pairs(match) do
+ for _, node in ipairs(nodes) do
+ table.insert(mrepr, { '@' .. cquery.captures[cid], node:type(), node:range() })
end
- table.insert(res, {pattern, mrepr})
end
- return res
- ]],
- '(expression_statement (assignment_expression (call_expression)))+ @funccall'
- )
+ table.insert(res, { pattern, mrepr })
+ end
+ return res
+ end, '(expression_statement (assignment_expression (call_expression)))+ @funccall')
eq({
{
@@ -249,23 +236,78 @@ void ui_refresh(void)
}, res)
end)
+ it('returns quantified matches in order of range #29344', function()
+ insert([[
+ int main() {
+ int a, b, c, d, e, f, g, h, i;
+ a = MIN(0, 1);
+ b = MIN(0, 1);
+ c = MIN(0, 1);
+ d = MIN(0, 1);
+ e = MIN(0, 1);
+ f = MIN(0, 1);
+ g = MIN(0, 1);
+ h = MIN(0, 1);
+ i = MIN(0, 1);
+ }
+ ]])
+
+ local res = exec_lua(function()
+ local cquery = vim.treesitter.query.parse(
+ 'c',
+ '(expression_statement (assignment_expression (call_expression)))+ @funccall'
+ )
+ local parser = vim.treesitter.get_parser(0, 'c')
+ local tree = parser:parse()[1]
+ local res = {}
+ for pattern, match in cquery:iter_matches(tree:root(), 0, 7, 14) do
+ -- can't transmit node over RPC. just check the name and range
+ local mrepr = {}
+ for cid, nodes in pairs(match) do
+ for _, node in ipairs(nodes) do
+ table.insert(mrepr, { '@' .. cquery.captures[cid], node:type(), node:range() })
+ end
+ end
+ table.insert(res, { pattern, mrepr })
+ end
+ return res
+ end)
+
+ eq({
+ {
+ 1,
+ {
+ { '@funccall', 'expression_statement', 2, 2, 2, 16 },
+ { '@funccall', 'expression_statement', 3, 2, 3, 16 },
+ { '@funccall', 'expression_statement', 4, 2, 4, 16 },
+ { '@funccall', 'expression_statement', 5, 2, 5, 16 },
+ { '@funccall', 'expression_statement', 6, 2, 6, 16 },
+ { '@funccall', 'expression_statement', 7, 2, 7, 16 },
+ { '@funccall', 'expression_statement', 8, 2, 8, 16 },
+ { '@funccall', 'expression_statement', 9, 2, 9, 16 },
+ { '@funccall', 'expression_statement', 10, 2, 10, 16 },
+ },
+ },
+ }, res)
+ end)
+
it('can match special regex characters like \\ * + ( with `vim-match?`', function()
insert('char* astring = "\\n"; (1 + 1) * 2 != 2;')
---@type table
- local res = exec_lua([[
- query = (
- '([_] @plus (#vim-match? @plus "^\\\\+$"))' ..
- '([_] @times (#vim-match? @times "^\\\\*$"))' ..
- '([_] @paren (#vim-match? @paren "^\\\\($"))' ..
- '([_] @escape (#vim-match? @escape "^\\\\\\\\n$"))' ..
- '([_] @string (#vim-match? @string "^\\"\\\\\\\\n\\"$"))'
+ local res = exec_lua(function()
+ local query = (
+ '([_] @plus (#vim-match? @plus "^\\\\+$"))'
+ .. '([_] @times (#vim-match? @times "^\\\\*$"))'
+ .. '([_] @paren (#vim-match? @paren "^\\\\($"))'
+ .. '([_] @escape (#vim-match? @escape "^\\\\\\\\n$"))'
+ .. '([_] @string (#vim-match? @string "^\\"\\\\\\\\n\\"$"))'
)
- cquery = vim.treesitter.query.parse("c", query)
- parser = vim.treesitter.get_parser(0, "c")
- tree = parser:parse()[1]
- res = {}
- for pattern, match in cquery:iter_matches(tree:root(), 0, 0, -1, { all = true }) do
+ local cquery = vim.treesitter.query.parse('c', query)
+ local parser = vim.treesitter.get_parser(0, 'c')
+ local tree = parser:parse()[1]
+ local res = {}
+ for pattern, match in cquery:iter_matches(tree:root(), 0, 0, -1) do
-- can't transmit node over RPC. just check the name and range
local mrepr = {}
for cid, nodes in pairs(match) do
@@ -276,7 +318,7 @@ void ui_refresh(void)
table.insert(res, { pattern, mrepr })
end
return res
- ]])
+ end)
eq({
{ 2, { { '@times', '*', 0, 4, 0, 5 } } },
@@ -307,10 +349,9 @@ void ui_refresh(void)
return 0;
}
]])
- exec_lua(get_query_result_code)
local res0 = exec_lua(
- [[return get_query_result(...)]],
+ get_query_result,
[[((primitive_type) @c-keyword (#any-of? @c-keyword "int" "float"))]]
)
eq({
@@ -319,7 +360,7 @@ void ui_refresh(void)
}, res0)
local res1 = exec_lua(
- [[return get_query_result(...)]],
+ get_query_result,
[[
((string_literal) @fizzbuzz-strings (#any-of? @fizzbuzz-strings
"\"number= %d FizzBuzz\\n\""
@@ -340,16 +381,15 @@ void ui_refresh(void)
int x = 123;
enum C { y = 124 };
int main() { int z = 125; }]])
- exec_lua(get_query_result_code)
local result = exec_lua(
- [[return get_query_result(...)]],
+ get_query_result,
[[((number_literal) @literal (#has-ancestor? @literal "function_definition"))]]
)
eq({ { 'literal', 'number_literal', { 2, 21, 2, 24 }, '125' } }, result)
result = exec_lua(
- [[return get_query_result(...)]],
+ get_query_result,
[[((number_literal) @literal (#has-ancestor? @literal "function_definition" "enum_specifier"))]]
)
eq({
@@ -358,7 +398,7 @@ void ui_refresh(void)
}, result)
result = exec_lua(
- [[return get_query_result(...)]],
+ get_query_result,
[[((number_literal) @literal (#not-has-ancestor? @literal "enum_specifier"))]]
)
eq({
@@ -370,12 +410,15 @@ void ui_refresh(void)
it('allows loading query with escaped quotes and capture them `#{lua,vim}-match`?', function()
insert('char* astring = "Hello World!";')
- local res = exec_lua([[
- cquery = vim.treesitter.query.parse("c", '([_] @quote (#vim-match? @quote "^\\"$")) ([_] @quote (#lua-match? @quote "^\\"$"))')
- parser = vim.treesitter.get_parser(0, "c")
- tree = parser:parse()[1]
- res = {}
- for pattern, match in cquery:iter_matches(tree:root(), 0, 0, -1, { all = true }) do
+ local res = exec_lua(function()
+ local cquery = vim.treesitter.query.parse(
+ 'c',
+ '([_] @quote (#vim-match? @quote "^\\"$")) ([_] @quote (#lua-match? @quote "^\\"$"))'
+ )
+ local parser = vim.treesitter.get_parser(0, 'c')
+ local tree = parser:parse()[1]
+ local res = {}
+ for pattern, match in cquery:iter_matches(tree:root(), 0, 0, -1) do
-- can't transmit node over RPC. just check the name and range
local mrepr = {}
for cid, nodes in pairs(match) do
@@ -386,7 +429,7 @@ void ui_refresh(void)
table.insert(res, { pattern, mrepr })
end
return res
- ]])
+ end)
eq({
{ 1, { { '@quote', '"', 0, 16, 0, 17 } } },
@@ -406,70 +449,60 @@ void ui_refresh(void)
local custom_query = '((identifier) @main (#is-main? @main))'
do
- local res = exec_lua(
- [[
- local query = vim.treesitter.query
-
- local function is_main(match, pattern, bufnr, predicate)
- local nodes = match[ predicate[2] ]
- for _, node in ipairs(nodes) do
- if vim.treesitter.get_node_text(node, bufnr) == 'main' then
- return true
- end
+ local res = exec_lua(function()
+ local query = vim.treesitter.query
+
+ local function is_main(match, _pattern, bufnr, predicate)
+ local nodes = match[predicate[2]]
+ for _, node in ipairs(nodes) do
+ if vim.treesitter.get_node_text(node, bufnr) == 'main' then
+ return true
end
- return false
end
+ return false
+ end
- local parser = vim.treesitter.get_parser(0, "c")
+ local parser = vim.treesitter.get_parser(0, 'c')
- -- Time bomb: update this in 0.12
- if vim.fn.has('nvim-0.12') == 1 then
- return 'Update this test to remove this message and { all = true } from add_predicate'
- end
- query.add_predicate("is-main?", is_main, { all = true })
+ query.add_predicate('is-main?', is_main)
- local query = query.parse("c", ...)
+ local query0 = query.parse('c', custom_query)
- local nodes = {}
- for _, node in query:iter_captures(parser:parse()[1]:root(), 0) do
- table.insert(nodes, {node:range()})
- end
+ local nodes = {}
+ for _, node in query0:iter_captures(parser:parse()[1]:root(), 0) do
+ table.insert(nodes, { node:range() })
+ end
- return nodes
- ]],
- custom_query
- )
+ return nodes
+ end)
eq({ { 0, 4, 0, 8 } }, res)
end
-- Once with the old API. Remove this whole 'do' block in 0.12
do
- local res = exec_lua(
- [[
- local query = vim.treesitter.query
+ local res = exec_lua(function()
+ local query = vim.treesitter.query
- local function is_main(match, pattern, bufnr, predicate)
- local node = match[ predicate[2] ]
+ local function is_main(match, _pattern, bufnr, predicate)
+ local node = match[predicate[2]]
- return vim.treesitter.get_node_text(node, bufnr) == 'main'
- end
+ return vim.treesitter.get_node_text(node, bufnr) == 'main'
+ end
- local parser = vim.treesitter.get_parser(0, "c")
+ local parser = vim.treesitter.get_parser(0, 'c')
- query.add_predicate("is-main?", is_main, true)
+ query.add_predicate('is-main?', is_main, { all = false, force = true })
- local query = query.parse("c", ...)
+ local query0 = query.parse('c', custom_query)
- local nodes = {}
- for _, node in query:iter_captures(parser:parse()[1]:root(), 0) do
- table.insert(nodes, {node:range()})
- end
+ local nodes = {}
+ for _, node in query0:iter_captures(parser:parse()[1]:root(), 0) do
+ table.insert(nodes, { node:range() })
+ end
- return nodes
- ]],
- custom_query
- )
+ return nodes
+ end)
-- Remove this 'do' block in 0.12
eq(0, fn.has('nvim-0.12'))
@@ -477,16 +510,16 @@ void ui_refresh(void)
end
do
- local res = exec_lua [[
+ local res = exec_lua(function()
local query = vim.treesitter.query
- local t = {}
+ local r = {}
for _, v in ipairs(query.list_predicates()) do
- t[v] = true
+ r[v] = true
end
- return t
- ]]
+ return r
+ end)
eq(true, res['is-main?'])
end
@@ -505,18 +538,15 @@ void ui_refresh(void)
local function test(input, query)
api.nvim_buf_set_lines(0, 0, -1, true, vim.split(dedent(input), '\n'))
- return exec_lua(
- [[
- local parser = vim.treesitter.get_parser(0, "lua")
- local query = vim.treesitter.query.parse("lua", ...)
- local nodes = {}
- for _, node in query:iter_captures(parser:parse()[1]:root(), 0) do
- nodes[#nodes+1] = { node:range() }
- end
- return nodes
- ]],
- query
- )
+ return exec_lua(function()
+ local parser = vim.treesitter.get_parser(0, 'lua')
+ local query0 = vim.treesitter.query.parse('lua', query)
+ local nodes = {}
+ for _, node in query0:iter_captures(parser:parse()[1]:root(), 0) do
+ nodes[#nodes + 1] = { node:range() }
+ end
+ return nodes
+ end)
end
eq(
@@ -583,23 +613,21 @@ void ui_refresh(void)
-- Comment
]])
- local query = [[
+ local result = exec_lua(function()
+ local parser = vim.treesitter.get_parser(0, 'lua')
+ local query = vim.treesitter.query.parse(
+ 'lua',
+ [[
(((comment (comment_content))+) @bar
(#lua-match? @bar "Comment"))
]]
-
- local result = exec_lua(
- [[
- local parser = vim.treesitter.get_parser(0, "lua")
- local query = vim.treesitter.query.parse("lua", ...)
- local nodes = {}
- for _, node in query:iter_captures(parser:parse()[1]:root(), 0) do
- nodes[#nodes+1] = { node:range() }
- end
- return nodes
- ]],
- query
- )
+ )
+ local nodes = {}
+ for _, node in query:iter_captures(parser:parse()[1]:root(), 0) do
+ nodes[#nodes + 1] = { node:range() }
+ end
+ return nodes
+ end)
eq({
{ 0, 2, 0, 12 },
@@ -613,23 +641,20 @@ void ui_refresh(void)
eq(0, fn.has('nvim-0.12'))
insert(test_text)
- local res = exec_lua(
- [[
- cquery = vim.treesitter.query.parse("c", ...)
- parser = vim.treesitter.get_parser(0, "c")
- tree = parser:parse()[1]
- res = {}
- for pattern, match in cquery:iter_matches(tree:root(), 0, 7, 14) do
- local mrepr = {}
- for cid, node in pairs(match) do
- table.insert(mrepr, { '@' .. cquery.captures[cid], node:type(), node:range() })
- end
- table.insert(res, { pattern, mrepr })
+ local res = exec_lua(function()
+ local cquery = vim.treesitter.query.parse('c', test_query)
+ local parser = vim.treesitter.get_parser(0, 'c')
+ local tree = parser:parse()[1]
+ local res = {}
+ for pattern, match in cquery:iter_matches(tree:root(), 0, 7, 14, { all = false }) do
+ local mrepr = {}
+ for cid, node in pairs(match) do
+ table.insert(mrepr, { '@' .. cquery.captures[cid], node:type(), node:range() })
end
- return res
- ]],
- test_query
- )
+ table.insert(res, { pattern, mrepr })
+ end
+ return res
+ end)
eq({
{ 3, { { '@type', 'primitive_type', 8, 2, 8, 6 } } },
@@ -661,23 +686,19 @@ void ui_refresh(void)
int bar = 13;
]]
- local ret = exec_lua(
- [[
- local str = ...
- local parser = vim.treesitter.get_string_parser(str, "c")
+ local ret = exec_lua(function()
+ local parser = vim.treesitter.get_string_parser(txt, 'c')
- local nodes = {}
- local query = vim.treesitter.query.parse("c", '((identifier) @foo)')
- local first_child = parser:parse()[1]:root():child(1)
+ local nodes = {}
+ local query = vim.treesitter.query.parse('c', '((identifier) @foo)')
+ local first_child = assert(parser:parse()[1]:root():child(1))
- for _, node in query:iter_captures(first_child, str) do
- table.insert(nodes, { node:range() })
- end
+ for _, node in query:iter_captures(first_child, txt) do
+ table.insert(nodes, { node:range() })
+ end
- return nodes
- ]],
- txt
- )
+ return nodes
+ end)
eq({ { 1, 10, 1, 13 } }, ret)
end)
@@ -734,7 +755,10 @@ void ui_refresh(void)
const char *sql = "SELECT * FROM Students WHERE name = 'Robert'); DROP TABLE Students;--";
]])
- local query = [[
+ local result = exec_lua(function()
+ local query = vim.treesitter.query.parse(
+ 'c',
+ [[
(declaration
type: (_)
declarator: (init_declarator
@@ -745,20 +769,15 @@ void ui_refresh(void)
(#set! injection.language "sql")
(#contains? @_id "sql"))
]]
-
- local result = exec_lua(
- [=[
- local query = vim.treesitter.query.parse("c", ...)
- local parser = vim.treesitter.get_parser(0, "c")
+ )
+ local parser = vim.treesitter.get_parser(0, 'c')
local root = parser:parse()[1]:root()
- local t = {}
- for id, node, metadata in query:iter_captures(root, 0) do
- t[query.captures[id]] = metadata
+ local res = {}
+ for id, _, metadata in query:iter_captures(root, 0) do
+ res[query.captures[id]] = metadata
end
- return t
- ]=],
- query
- )
+ return res
+ end)
eq({
['_id'] = { ['injection.language'] = 'sql' },
@@ -782,25 +801,22 @@ void ui_refresh(void)
(#eq? @function.name "foo"))
]]
- local result = exec_lua(
- [[
- local query = vim.treesitter.query.parse("c", ...)
- local match_preds = query.match_preds
+ local result = exec_lua(function()
+ local query0 = vim.treesitter.query.parse('c', query)
+ local match_preds = query0.match_preds
local called = 0
- function query:match_preds(...)
+ function query0:match_preds(...)
called = called + 1
return match_preds(self, ...)
end
- local parser = vim.treesitter.get_parser(0, "c")
+ local parser = vim.treesitter.get_parser(0, 'c')
local root = parser:parse()[1]:root()
local captures = {}
- for id, node in query:iter_captures(root, 0) do
+ for id in query0:iter_captures(root, 0) do
captures[#captures + 1] = id
end
return { called, captures }
- ]],
- query
- )
+ end)
eq({ 2, { 1, 1, 2, 2 } }, result)
end)
diff --git a/test/functional/treesitter/utils_spec.lua b/test/functional/treesitter/utils_spec.lua
index bca0aca0cb..34bea349f6 100644
--- a/test/functional/treesitter/utils_spec.lua
+++ b/test/functional/treesitter/utils_spec.lua
@@ -17,26 +17,30 @@ describe('treesitter utils', function()
int x = 3;
}]])
- exec_lua([[
- parser = vim.treesitter.get_parser(0, "c")
- tree = parser:parse()[1]
- root = tree:root()
- ancestor = root:child(0)
- child = ancestor:child(0)
- ]])
-
- eq(true, exec_lua('return vim.treesitter.is_ancestor(ancestor, child)'))
- eq(false, exec_lua('return vim.treesitter.is_ancestor(child, ancestor)'))
+ exec_lua(function()
+ local parser = vim.treesitter.get_parser(0, 'c')
+ local tree = parser:parse()[1]
+ local root = tree:root()
+ _G.ancestor = assert(root:child(0))
+ _G.child = assert(_G.ancestor:named_child(1))
+ _G.child_sibling = assert(_G.ancestor:named_child(2))
+ _G.grandchild = assert(_G.child:named_child(0))
+ end)
+
+ eq(true, exec_lua('return vim.treesitter.is_ancestor(_G.ancestor, _G.child)'))
+ eq(true, exec_lua('return vim.treesitter.is_ancestor(_G.ancestor, _G.grandchild)'))
+ eq(false, exec_lua('return vim.treesitter.is_ancestor(_G.child, _G.ancestor)'))
+ eq(false, exec_lua('return vim.treesitter.is_ancestor(_G.child, _G.child_sibling)'))
end)
it('can detect if a position is contained in a node', function()
- exec_lua([[
- node = {
+ exec_lua(function()
+ _G.node = {
range = function()
return 0, 4, 0, 8
end,
}
- ]])
+ end)
eq(false, exec_lua('return vim.treesitter.is_in_node_range(node, 0, 3)'))
for i = 4, 7 do