test: allow exec_lua to handle functions

Problem:

Tests have lots of exec_lua calls which input blocks of code
provided as unformatted strings.

Solution:

Teach exec_lua how to handle functions.
This commit is contained in:
Lewis Russell
2024-07-29 11:20:15 +01:00
committed by Lewis Russell
parent f32557ca67
commit 7d24c4d6b0
16 changed files with 4122 additions and 3891 deletions

View File

@@ -145,10 +145,10 @@ describe('luaeval(vim.api.…)', function()
eq(true, fn.luaeval('vim.api.nvim__id(vim.api.nvim__id)(true)')) eq(true, fn.luaeval('vim.api.nvim__id(vim.api.nvim__id)(true)'))
eq( eq(
42, 42,
exec_lua [[ exec_lua(function()
local f = vim.api.nvim__id({42, vim.api.nvim__id}) local f = vim.api.nvim__id({ 42, vim.api.nvim__id })
return f[2](f[1]) return f[2](f[1])
]] end)
) )
end) end)

View File

@@ -27,30 +27,35 @@ local origlines = {
before_each(function() before_each(function()
clear() clear()
exec_lua [[ exec_lua(function()
local evname = ...
local events = {} local events = {}
function test_register(bufnr, evname, id, changedtick, utf_sizes, preview) function _G.test_register(bufnr, evname, id, changedtick, utf_sizes, preview)
local function callback(...) local function callback(...)
table.insert(events, {id, ...}) table.insert(events, { id, ... })
if test_unreg == id then if _G.test_unreg == id then
return true return true
end end
end end
local opts = {[evname]=callback, on_detach=callback, on_reload=callback, utf_sizes=utf_sizes, preview=preview} local opts = {
[evname] = callback,
on_detach = callback,
on_reload = callback,
utf_sizes = utf_sizes,
preview = preview,
}
if changedtick then if changedtick then
opts.on_changedtick = callback opts.on_changedtick = callback
end end
vim.api.nvim_buf_attach(bufnr, false, opts) vim.api.nvim_buf_attach(bufnr, false, opts)
end end
function get_events() function _G.get_events()
local ret_events = events local ret_events = events
events = {} events = {}
return ret_events return ret_events
end end
]] end)
end) end)
describe('lua buffer event callbacks: on_lines', function() describe('lua buffer event callbacks: on_lines', function()
@@ -257,13 +262,13 @@ describe('lua buffer event callbacks: on_lines', function()
it('has valid cursor position while shifting', function() it('has valid cursor position while shifting', function()
api.nvim_buf_set_lines(0, 0, -1, true, { 'line1' }) api.nvim_buf_set_lines(0, 0, -1, true, { 'line1' })
exec_lua([[ exec_lua(function()
vim.api.nvim_buf_attach(0, false, { vim.api.nvim_buf_attach(0, false, {
on_lines = function() on_lines = function()
vim.api.nvim_set_var('listener_cursor_line', vim.api.nvim_win_get_cursor(0)[1]) vim.api.nvim_set_var('listener_cursor_line', vim.api.nvim_win_get_cursor(0)[1])
end, end,
}) })
]]) end)
feed('>>') feed('>>')
eq(1, api.nvim_get_var('listener_cursor_line')) eq(1, api.nvim_get_var('listener_cursor_line'))
end) end)
@@ -302,13 +307,13 @@ describe('lua buffer event callbacks: on_lines', function()
it('#12718 lnume', function() it('#12718 lnume', function()
api.nvim_buf_set_lines(0, 0, -1, true, { '1', '2', '3' }) api.nvim_buf_set_lines(0, 0, -1, true, { '1', '2', '3' })
exec_lua([[ exec_lua(function()
vim.api.nvim_buf_attach(0, false, { vim.api.nvim_buf_attach(0, false, {
on_lines = function(...) on_lines = function(...)
vim.api.nvim_set_var('linesev', { ... }) vim.api.nvim_set_var('linesev', { ... })
end, end,
}) })
]]) end)
feed('1G0') feed('1G0')
feed('y<C-v>2j') feed('y<C-v>2j')
feed('G0') feed('G0')
@@ -326,13 +331,13 @@ describe('lua buffer event callbacks: on_lines', function()
end) end)
it('nvim_buf_call() from callback does not cause wrong Normal mode CTRL-A #16729', function() it('nvim_buf_call() from callback does not cause wrong Normal mode CTRL-A #16729', function()
exec_lua([[ exec_lua(function()
vim.api.nvim_buf_attach(0, false, { vim.api.nvim_buf_attach(0, false, {
on_lines = function(...) on_lines = function()
vim.api.nvim_buf_call(0, function() end) vim.api.nvim_buf_call(0, function() end)
end, end,
}) })
]]) end)
feed('itest123<Esc><C-A>') feed('itest123<Esc><C-A>')
eq('test124', api.nvim_get_current_line()) eq('test124', api.nvim_get_current_line())
end) end)
@@ -342,19 +347,19 @@ describe('lua buffer event callbacks: on_lines', function()
screen:attach() screen:attach()
api.nvim_buf_set_lines(0, 0, -1, true, { 'aaa', 'bbb', 'ccc' }) api.nvim_buf_set_lines(0, 0, -1, true, { 'aaa', 'bbb', 'ccc' })
exec_lua([[ exec_lua(function()
local ns = vim.api.nvim_create_namespace('') local ns = vim.api.nvim_create_namespace('')
vim.api.nvim_buf_attach(0, false, { vim.api.nvim_buf_attach(0, false, {
on_lines = function(_, _, _, row, _, end_row) on_lines = function(_, _, _, row, _, end_row)
vim.api.nvim_buf_clear_namespace(0, ns, row, end_row) vim.api.nvim_buf_clear_namespace(0, ns, row, end_row)
for i = row, end_row - 1 do for i = row, end_row - 1 do
local id = vim.api.nvim_buf_set_extmark(0, ns, i, 0, { vim.api.nvim_buf_set_extmark(0, ns, i, 0, {
virt_text = {{ 'NEW' .. tostring(i), 'WarningMsg' }}, virt_text = { { 'NEW' .. tostring(i), 'WarningMsg' } },
}) })
end end
end, end,
}) })
]]) end)
feed('o') feed('o')
screen:expect({ screen:expect({
@@ -383,7 +388,7 @@ describe('lua buffer event callbacks: on_lines', function()
it('line lengths are correct when pressing TAB with folding #29119', function() it('line lengths are correct when pressing TAB with folding #29119', function()
api.nvim_buf_set_lines(0, 0, -1, true, { 'a', 'b' }) api.nvim_buf_set_lines(0, 0, -1, true, { 'a', 'b' })
exec_lua([[ exec_lua(function()
_G.res = {} _G.res = {}
vim.o.foldmethod = 'indent' vim.o.foldmethod = 'indent'
vim.o.softtabstop = -1 vim.o.softtabstop = -1
@@ -391,9 +396,9 @@ describe('lua buffer event callbacks: on_lines', function()
on_lines = function(_, bufnr, _, row, _, end_row) on_lines = function(_, bufnr, _, row, _, end_row)
local lines = vim.api.nvim_buf_get_lines(bufnr, row, end_row, true) local lines = vim.api.nvim_buf_get_lines(bufnr, row, end_row, true)
table.insert(_G.res, lines) table.insert(_G.res, lines)
end end,
}) })
]]) end)
feed('i<Tab>') feed('i<Tab>')
eq({ '\ta' }, exec_lua('return _G.res[#_G.res]')) eq({ '\ta' }, exec_lua('return _G.res[#_G.res]'))

View File

@@ -178,13 +178,15 @@ describe(':lua', function()
eq('hello', exec_capture(':lua = x()')) eq('hello', exec_capture(':lua = x()'))
exec_lua('x = {a = 1, b = 2}') exec_lua('x = {a = 1, b = 2}')
eq('{\n a = 1,\n b = 2\n}', exec_capture(':lua =x')) eq('{\n a = 1,\n b = 2\n}', exec_capture(':lua =x'))
exec_lua([[function x(success) exec_lua(function()
if success then function _G.x(success)
return true, "Return value" if success then
else return true, 'Return value'
return false, nil, "Error message" else
return false, nil, 'Error message'
end
end end
end]]) end)
eq( eq(
dedent [[ dedent [[
true true

File diff suppressed because it is too large Load Diff

View File

@@ -18,90 +18,82 @@ describe('vim.filetype', function()
before_each(function() before_each(function()
clear() clear()
exec_lua [[ exec_lua(function()
local bufnr = vim.api.nvim_create_buf(true, false) local bufnr = vim.api.nvim_create_buf(true, false)
vim.api.nvim_set_current_buf(bufnr) vim.api.nvim_set_current_buf(bufnr)
]] end)
end) end)
it('works with extensions', function() it('works with extensions', function()
eq( eq(
'radicalscript', 'radicalscript',
exec_lua [[ exec_lua(function()
vim.filetype.add({ vim.filetype.add({
extension = { extension = {
rs = 'radicalscript', rs = 'radicalscript',
}, },
}) })
return vim.filetype.match({ filename = 'main.rs' }) return vim.filetype.match({ filename = 'main.rs' })
]] end)
) )
end) end)
it('prioritizes filenames over extensions', function() it('prioritizes filenames over extensions', function()
eq( eq(
'somethingelse', 'somethingelse',
exec_lua [[ exec_lua(function()
vim.filetype.add({ vim.filetype.add({
extension = { extension = {
rs = 'radicalscript', rs = 'radicalscript',
}, },
filename = { filename = {
['main.rs'] = 'somethingelse', ['main.rs'] = 'somethingelse',
}, },
}) })
return vim.filetype.match({ filename = 'main.rs' }) return vim.filetype.match({ filename = 'main.rs' })
]] end)
) )
end) end)
it('works with filenames', function() it('works with filenames', function()
eq( eq(
'nim', 'nim',
exec_lua [[ exec_lua(function()
vim.filetype.add({ vim.filetype.add({
filename = { filename = {
['s_O_m_e_F_i_l_e'] = 'nim', ['s_O_m_e_F_i_l_e'] = 'nim',
}, },
}) })
return vim.filetype.match({ filename = 's_O_m_e_F_i_l_e' }) return vim.filetype.match({ filename = 's_O_m_e_F_i_l_e' })
]] end)
) )
eq( eq(
'dosini', 'dosini',
exec_lua( exec_lua(function(root0)
[[ vim.filetype.add({
local root = ... filename = {
vim.filetype.add({ ['config'] = 'toml',
filename = { [root0 .. '/.config/fun/config'] = 'dosini',
['config'] = 'toml', },
[root .. '/.config/fun/config'] = 'dosini', })
}, return vim.filetype.match({ filename = root0 .. '/.config/fun/config' })
}) end, root)
return vim.filetype.match({ filename = root .. '/.config/fun/config' })
]],
root
)
) )
end) end)
it('works with patterns', function() it('works with patterns', function()
eq( eq(
'markdown', 'markdown',
exec_lua( exec_lua(function()
[[ vim.env.HOME = '/a-funky+home%dir'
local root = ... vim.filetype.add({
vim.env.HOME = '/a-funky+home%dir' pattern = {
vim.filetype.add({ ['~/blog/.*%.txt'] = 'markdown',
pattern = { },
['~/blog/.*%.txt'] = 'markdown', })
} return vim.filetype.match({ filename = '~/blog/why_neovim_is_awesome.txt' })
}) end)
return vim.filetype.match({ filename = '~/blog/why_neovim_is_awesome.txt' })
]],
root
)
) )
end) end)
@@ -110,43 +102,43 @@ describe('vim.filetype', function()
command('file relevant_to_me') command('file relevant_to_me')
eq( eq(
'foss', 'foss',
exec_lua [[ exec_lua(function()
vim.filetype.add({ vim.filetype.add({
pattern = { pattern = {
["relevant_to_(%a+)"] = function(path, bufnr, capture) ['relevant_to_(%a+)'] = function(_, _, capture)
if capture == "me" then if capture == 'me' then
return "foss" return 'foss'
end end
end, end,
} },
}) })
return vim.filetype.match({ buf = 0 }) return vim.filetype.match({ buf = 0 })
]] end)
) )
end) end)
it('works with contents #22180', function() it('works with contents #22180', function()
eq( eq(
'sh', 'sh',
exec_lua [[ exec_lua(function()
-- Needs to be set so detect#sh doesn't fail -- Needs to be set so detect#sh doesn't fail
vim.g.ft_ignore_pat = '\\.\\(Z\\|gz\\|bz2\\|zip\\|tgz\\)$' vim.g.ft_ignore_pat = '\\.\\(Z\\|gz\\|bz2\\|zip\\|tgz\\)$'
return vim.filetype.match({ contents = { '#!/usr/bin/env bash' } }) return vim.filetype.match({ contents = { '#!/usr/bin/env bash' } })
]] end)
) )
end) end)
it('considers extension mappings when matching from hashbang', function() it('considers extension mappings when matching from hashbang', function()
eq( eq(
'fooscript', 'fooscript',
exec_lua [[ exec_lua(function()
vim.filetype.add({ vim.filetype.add({
extension = { extension = {
foo = 'fooscript', foo = 'fooscript',
} },
}) })
return vim.filetype.match({ contents = { '#!/usr/bin/env foo' } }) return vim.filetype.match({ contents = { '#!/usr/bin/env foo' } })
]] end)
) )
end) end)

View File

@@ -141,19 +141,14 @@ describe('vim.fs', function()
it('works', function() it('works', function()
eq( eq(
true, true,
exec_lua( exec_lua(function(dir, nvim)
[[ for name, type in vim.fs.dir(dir) do
local dir, nvim = ... if name == nvim and type == 'file' then
for name, type in vim.fs.dir(dir) do return true
if name == nvim and type == 'file' then end
return true
end end
end return false
return false end, nvim_dir, nvim_prog_basename)
]],
nvim_dir,
nvim_prog_basename
)
) )
end) end)
@@ -172,27 +167,21 @@ describe('vim.fs', function()
io.open('testd/a/b/c/c4', 'w'):close() io.open('testd/a/b/c/c4', 'w'):close()
local function run(dir, depth, skip) local function run(dir, depth, skip)
local r = exec_lua( local r = exec_lua(function(dir0, depth0, skip0)
[[
local dir, depth, skip = ...
local r = {} local r = {}
local skip_f local skip_f
if skip then if skip0 then
skip_f = function(n) skip_f = function(n0)
if vim.tbl_contains(skip or {}, n) then if vim.tbl_contains(skip0 or {}, n0) then
return false return false
end end
end end
end end
for name, type_ in vim.fs.dir(dir, { depth = depth, skip = skip_f }) do for name, type_ in vim.fs.dir(dir0, { depth = depth0, skip = skip_f }) do
r[name] = type_ r[name] = type_
end end
return r return r
]], end, dir, depth, skip)
dir,
depth,
skip
)
return r return r
end end
@@ -263,13 +252,9 @@ describe('vim.fs', function()
opts = { path = test_source_path .. '/contrib', limit = math.huge } opts = { path = test_source_path .. '/contrib', limit = math.huge }
eq( eq(
exec_lua( exec_lua(function(dir)
[[ return vim.tbl_map(vim.fs.basename, vim.fn.glob(dir .. '/contrib/*', false, true))
local dir = ... end, test_source_path),
return vim.tbl_map(vim.fs.basename, vim.fn.glob(dir..'/contrib/*', false, true))
]],
test_source_path
),
vim.tbl_map( vim.tbl_map(
vim.fs.basename, vim.fs.basename,
vim.fs.find(function(_, d) vim.fs.find(function(_, d)
@@ -299,11 +284,11 @@ describe('vim.fs', function()
it('works with a function', function() it('works with a function', function()
---@type string ---@type string
local result = exec_lua([[ local result = exec_lua(function()
return vim.fs.root(0, function(name, path) return vim.fs.root(0, function(name, _)
return name:match('%.txt$') return name:match('%.txt$')
end) end)
]]) end)
eq(vim.fs.joinpath(test_source_path, 'test/functional/fixtures'), result) eq(vim.fs.joinpath(test_source_path, 'test/functional/fixtures'), result)
end) end)
@@ -352,13 +337,10 @@ describe('vim.fs', function()
local xdg_config_home = test_build_dir .. '/.config' local xdg_config_home = test_build_dir .. '/.config'
eq( eq(
xdg_config_home .. '/nvim', xdg_config_home .. '/nvim',
exec_lua( exec_lua(function(...)
[[ vim.env.XDG_CONFIG_HOME = ...
vim.env.XDG_CONFIG_HOME = ... return vim.fs.normalize('$XDG_CONFIG_HOME/nvim')
return vim.fs.normalize('$XDG_CONFIG_HOME/nvim') end, xdg_config_home)
]],
xdg_config_home
)
) )
end) end)

View File

@@ -9,14 +9,9 @@ describe('glob', function()
after_each(n.clear) after_each(n.clear)
local match = function(...) local match = function(...)
return exec_lua( return exec_lua(function(pattern, str)
[[ return require('vim.glob').to_lpeg(pattern):match(str) ~= nil
local pattern = select(1, ...) end, ...)
local str = select(2, ...)
return require("vim.glob").to_lpeg(pattern):match(str) ~= nil
]],
...
)
end end
describe('glob matching', function() describe('glob matching', function()

File diff suppressed because it is too large Load Diff

View File

@@ -48,13 +48,13 @@ void ui_refresh(void)
end end
local function get_fold_levels() local function get_fold_levels()
return exec_lua([[ return exec_lua(function()
local res = {} local res = {}
for i = 1, vim.api.nvim_buf_line_count(0) do for i = 1, vim.api.nvim_buf_line_count(0) do
res[i] = vim.treesitter.foldexpr(i) res[i] = vim.treesitter.foldexpr(i)
end end
return res return res
]]) end)
end end
it('can compute fold levels', function() it('can compute fold levels', function()
@@ -246,9 +246,13 @@ function f()
end end
-- comment]]) -- comment]])
exec_lua( exec_lua(function()
[[vim.treesitter.query.set('lua', 'folds', '[(function_declaration) (parameters) (arguments)] @fold')]] vim.treesitter.query.set(
) 'lua',
'folds',
'[(function_declaration) (parameters) (arguments)] @fold'
)
end)
parse('lua') parse('lua')
eq({ eq({
@@ -290,9 +294,13 @@ function f()
) )
end]]) end]])
exec_lua( exec_lua(function()
[[vim.treesitter.query.set('lua', 'folds', '[(function_declaration) (function_definition) (parameters) (arguments)] @fold')]] vim.treesitter.query.set(
) 'lua',
'folds',
'[(function_declaration) (function_definition) (parameters) (arguments)] @fold'
)
end)
parse('lua') parse('lua')
-- If fold1.stop = fold2.start, then move fold1's stop up so that fold2.start gets proper level. -- 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
end]]) end]])
exec_lua( exec_lua(function()
[[vim.treesitter.query.set('lua', 'folds', '[(if_statement) (function_declaration) (parameters) (arguments) (table_constructor)] @fold')]] vim.treesitter.query.set(
) 'lua',
'folds',
'[(if_statement) (function_declaration) (parameters) (arguments) (table_constructor)] @fold'
)
end)
parse('lua') parse('lua')
eq({ eq({

View File

@@ -156,7 +156,7 @@ local injection_grid_expected_c = [[
]] ]]
describe('treesitter highlighting (C)', function() describe('treesitter highlighting (C)', function()
local screen local screen --- @type test.functional.ui.screen
before_each(function() before_each(function()
clear() clear()
@@ -176,7 +176,6 @@ describe('treesitter highlighting (C)', function()
[11] = { foreground = Screen.colors.Cyan4 }, [11] = { foreground = Screen.colors.Cyan4 },
} }
exec_lua([[ hl_query = ... ]], hl_query_c)
command [[ hi link @error ErrorMsg ]] command [[ hi link @error ErrorMsg ]]
command [[ hi link @warning WarningMsg ]] command [[ hi link @warning WarningMsg ]]
end) end)
@@ -188,22 +187,28 @@ describe('treesitter highlighting (C)', function()
-- legacy syntax highlighting is used by default -- legacy syntax highlighting is used by default
screen:expect(hl_grid_legacy_c) screen:expect(hl_grid_legacy_c)
exec_lua([[ exec_lua(function(hl_query)
vim.treesitter.query.set('c', 'highlights', hl_query) vim.treesitter.query.set('c', 'highlights', hl_query)
vim.treesitter.start() vim.treesitter.start()
]]) end, hl_query_c)
-- treesitter highlighting is used -- treesitter highlighting is used
screen:expect(hl_grid_ts_c) screen:expect(hl_grid_ts_c)
exec_lua('vim.treesitter.stop()') exec_lua(function()
vim.treesitter.stop()
end)
-- legacy syntax highlighting is used -- legacy syntax highlighting is used
screen:expect(hl_grid_legacy_c) screen:expect(hl_grid_legacy_c)
exec_lua('vim.treesitter.start()') exec_lua(function()
vim.treesitter.start()
end)
-- treesitter highlighting is used -- treesitter highlighting is used
screen:expect(hl_grid_ts_c) screen:expect(hl_grid_ts_c)
exec_lua('vim.treesitter.stop()') exec_lua(function()
vim.treesitter.stop()
end)
-- legacy syntax highlighting is used -- legacy syntax highlighting is used
screen:expect(hl_grid_legacy_c) screen:expect(hl_grid_legacy_c)
end) end)
@@ -233,11 +238,11 @@ describe('treesitter highlighting (C)', function()
]], ]],
} }
exec_lua [[ exec_lua(function(hl_query)
local parser = vim.treesitter.get_parser(0, "c") local parser = vim.treesitter.get_parser(0, 'c')
local highlighter = vim.treesitter.highlighter local highlighter = vim.treesitter.highlighter
test_hl = highlighter.new(parser, {queries = {c = hl_query}}) highlighter.new(parser, { queries = { c = hl_query } })
]] end, hl_query_c)
screen:expect(hl_grid_ts_c) screen:expect(hl_grid_ts_c)
feed('5Goc<esc>dd') feed('5Goc<esc>dd')
@@ -364,10 +369,10 @@ describe('treesitter highlighting (C)', function()
it('is updated with :sort', function() it('is updated with :sort', function()
insert(test_text_c) insert(test_text_c)
exec_lua [[ exec_lua(function(hl_query)
local parser = vim.treesitter.get_parser(0, "c") local parser = vim.treesitter.get_parser(0, 'c')
test_hl = vim.treesitter.highlighter.new(parser, {queries = {c = hl_query}}) vim.treesitter.highlighter.new(parser, { queries = { c = hl_query } })
]] end, hl_query_c)
screen:expect { screen:expect {
grid = [[ grid = [[
{3:int} width = {5:INT_MAX}, height = {5:INT_MAX}; | {3:int} width = {5:INT_MAX}, height = {5:INT_MAX}; |
@@ -470,19 +475,19 @@ describe('treesitter highlighting (C)', function()
]], ]],
} }
exec_lua [[ exec_lua(function()
parser = vim.treesitter.get_parser(0, "c") local parser = vim.treesitter.get_parser(0, 'c')
query = vim.treesitter.query.parse("c", "(declaration) @decl") local query = vim.treesitter.query.parse('c', '(declaration) @decl')
local nodes = {} local nodes = {}
for _, node in query:iter_captures(parser:parse()[1]:root(), 0, 0, 19) do for _, node in query:iter_captures(parser:parse()[1]:root(), 0, 0, 19) do
table.insert(nodes, node) table.insert(nodes, node)
end 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 { screen:expect {
grid = [[ grid = [[
@@ -513,13 +518,15 @@ describe('treesitter highlighting (C)', function()
screen:expect { grid = injection_grid_c } screen:expect { grid = injection_grid_c }
exec_lua [[ exec_lua(function(hl_query)
local parser = vim.treesitter.get_parser(0, "c", { 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"))'} 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 local highlighter = vim.treesitter.highlighter
test_hl = highlighter.new(parser, {queries = {c = hl_query}}) highlighter.new(parser, { queries = { c = hl_query } })
]] end, hl_query_c)
screen:expect { grid = injection_grid_expected_c } screen:expect { grid = injection_grid_expected_c }
end) end)
@@ -529,14 +536,16 @@ describe('treesitter highlighting (C)', function()
screen:expect { grid = injection_grid_c } screen:expect { grid = injection_grid_c }
exec_lua [[ exec_lua(function(hl_query)
vim.treesitter.language.register("c", "foo") vim.treesitter.language.register('c', 'foo')
local parser = vim.treesitter.get_parser(0, "c", { 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"))'} 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 local highlighter = vim.treesitter.highlighter
test_hl = highlighter.new(parser, {queries = {c = hl_query}}) highlighter.new(parser, { queries = { c = hl_query } })
]] end, hl_query_c)
screen:expect { grid = injection_grid_expected_c } screen:expect { grid = injection_grid_expected_c }
end) end)
@@ -550,13 +559,14 @@ describe('treesitter highlighting (C)', function()
} }
]]) ]])
exec_lua [[ exec_lua(function(hl_query)
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"))' local injection_query =
vim.treesitter.query.set("c", "highlights", hl_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", "injections", injection_query) vim.treesitter.query.set('c', 'highlights', hl_query)
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, hl_query_c)
screen:expect { screen:expect {
grid = [[ grid = [[
@@ -576,10 +586,10 @@ describe('treesitter highlighting (C)', function()
insert(hl_text_c) insert(hl_text_c)
feed('gg') feed('gg')
exec_lua [[ exec_lua(function(hl_query)
local parser = vim.treesitter.get_parser(0, "c") local parser = vim.treesitter.get_parser(0, 'c')
test_hl = vim.treesitter.highlighter.new(parser, {queries = {c = hl_query}}) vim.treesitter.highlighter.new(parser, { queries = { c = hl_query } })
]] end, hl_query_c)
screen:expect(hl_grid_ts_c) screen:expect(hl_grid_ts_c)
@@ -619,10 +629,14 @@ describe('treesitter highlighting (C)', function()
} }
]]) ]])
exec_lua [[ exec_lua(function(hl_query)
local parser = vim.treesitter.get_parser(0, "c") 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'}}) vim.treesitter.highlighter.new(parser, {
]] queries = {
c = hl_query .. '\n((translation_unit) @constant (#set! "priority" 101))\n',
},
})
end, hl_query_c)
-- expect everything to have Constant highlight -- expect everything to have Constant highlight
screen:expect { screen:expect {
grid = [[ grid = [[
@@ -669,11 +683,14 @@ describe('treesitter highlighting (C)', function()
hi link @foo.bar Type hi link @foo.bar Type
hi link @foo String hi link @foo String
]] ]]
exec_lua [[ exec_lua(function()
local parser = vim.treesitter.get_parser(0, "c", {}) local parser = vim.treesitter.get_parser(0, 'c', {})
local highlighter = vim.treesitter.highlighter local highlighter = vim.treesitter.highlighter
test_hl = highlighter.new(parser, {queries = {c = "(primitive_type) @foo.bar (string_literal) @foo"}}) highlighter.new(
]] parser,
{ queries = { c = '(primitive_type) @foo.bar (string_literal) @foo' } }
)
end)
screen:expect { screen:expect {
grid = [[ grid = [[
@@ -701,10 +718,12 @@ describe('treesitter highlighting (C)', function()
insert(hl_text_c) insert(hl_text_c)
-- conceal can be empty or a single cchar. -- conceal can be empty or a single cchar.
exec_lua [=[ exec_lua(function()
vim.opt.cole = 2 vim.opt.cole = 2
local parser = vim.treesitter.get_parser(0, "c") local parser = vim.treesitter.get_parser(0, 'c')
test_hl = vim.treesitter.highlighter.new(parser, {queries = {c = [[ vim.treesitter.highlighter.new(parser, {
queries = {
c = [[
("static" @keyword ("static" @keyword
(#set! conceal "R")) (#set! conceal "R"))
@@ -717,8 +736,10 @@ describe('treesitter highlighting (C)', function()
arguments: (argument_list) @arguments) arguments: (argument_list) @arguments)
(#eq? @function "multiqueue_put") (#eq? @function "multiqueue_put")
(#set! @function conceal "V")) (#set! @function conceal "V"))
]]}}) ]],
]=] },
})
end)
screen:expect { screen:expect {
grid = [[ grid = [[
@@ -775,11 +796,11 @@ describe('treesitter highlighting (C)', function()
int z = 6; int z = 6;
]]) ]])
exec_lua([[ exec_lua(function()
local query = '((declaration)+ @string)' local query = '((declaration)+ @string)'
vim.treesitter.query.set('c', 'highlights', query) vim.treesitter.query.set('c', 'highlights', query)
vim.treesitter.highlighter.new(vim.treesitter.get_parser(0, 'c')) vim.treesitter.highlighter.new(vim.treesitter.get_parser(0, 'c'))
]]) end)
screen:expect { screen:expect {
grid = [[ grid = [[
@@ -805,14 +826,10 @@ describe('treesitter highlighting (C)', function()
declarator: (pointer_declarator) @variable.parameter) declarator: (pointer_declarator) @variable.parameter)
]] ]]
exec_lua( exec_lua(function(query_str)
[[ vim.treesitter.query.set('c', 'highlights', query_str)
local query = ...
vim.treesitter.query.set('c', 'highlights', query)
vim.treesitter.highlighter.new(vim.treesitter.get_parser(0, 'c')) vim.treesitter.highlighter.new(vim.treesitter.get_parser(0, 'c'))
]], end, query)
query
)
screen:expect { screen:expect {
grid = [[ grid = [[
@@ -847,10 +864,10 @@ describe('treesitter highlighting (lua)', function()
ffi.cdef("int (*fun)(int, char *);") ffi.cdef("int (*fun)(int, char *);")
]] ]]
exec_lua [[ exec_lua(function()
vim.bo.filetype = 'lua' vim.bo.filetype = 'lua'
vim.treesitter.start() vim.treesitter.start()
]] end)
screen:expect { screen:expect {
grid = [[ grid = [[
@@ -888,10 +905,10 @@ describe('treesitter highlighting (help)', function()
< <
]] ]]
exec_lua [[ exec_lua(function()
vim.bo.filetype = 'help' vim.bo.filetype = 'help'
vim.treesitter.start() vim.treesitter.start()
]] end)
screen:expect { screen:expect {
grid = [[ grid = [[
@@ -943,15 +960,15 @@ describe('treesitter highlighting (help)', function()
]] ]]
]=]) ]=])
exec_lua [[ exec_lua(function()
parser = vim.treesitter.get_parser(0, "lua", { local parser = vim.treesitter.get_parser(0, 'lua', {
injections = { injections = {
lua = '(string content: (_) @injection.content (#set! injection.language lua))' lua = '(string content: (_) @injection.content (#set! injection.language lua))',
} },
}) })
vim.treesitter.highlighter.new(parser) vim.treesitter.highlighter.new(parser)
]] end)
screen:expect { screen:expect {
grid = [=[ grid = [=[
@@ -967,7 +984,7 @@ describe('treesitter highlighting (help)', function()
end) end)
describe('treesitter highlighting (nested injections)', function() describe('treesitter highlighting (nested injections)', function()
local screen local screen --- @type test.functional.ui.screen
before_each(function() before_each(function()
clear() clear()
@@ -996,11 +1013,11 @@ vim.cmd([[
]]) ]])
]=] ]=]
exec_lua [[ exec_lua(function()
vim.opt.scrolloff = 0 vim.opt.scrolloff = 0
vim.bo.filetype = 'lua' vim.bo.filetype = 'lua'
vim.treesitter.start() vim.treesitter.start()
]] end)
-- invalidate the language tree -- invalidate the language tree
feed('ggi--[[<ESC>04x') feed('ggi--[[<ESC>04x')
@@ -1041,10 +1058,10 @@ describe('treesitter highlighting (markdown)', function()
clear() clear()
screen = Screen.new(40, 6) screen = Screen.new(40, 6)
screen:attach() screen:attach()
exec_lua([[ exec_lua(function()
vim.bo.filetype = 'markdown' vim.bo.filetype = 'markdown'
vim.treesitter.start() vim.treesitter.start()
]]) end)
end) end)
it('supports hyperlinks', function() it('supports hyperlinks', function()

View File

@@ -22,10 +22,10 @@ describe('vim.treesitter.inspect_tree', function()
print() print()
]]) ]])
exec_lua([[ exec_lua(function()
vim.treesitter.start(0, 'lua') vim.treesitter.start(0, 'lua')
vim.treesitter.inspect_tree() vim.treesitter.inspect_tree()
]]) end)
expect_tree [[ expect_tree [[
(chunk ; [0, 0] - [2, 0] (chunk ; [0, 0] - [2, 0]
@@ -40,10 +40,10 @@ describe('vim.treesitter.inspect_tree', function()
print('hello') print('hello')
]]) ]])
exec_lua([[ exec_lua(function()
vim.treesitter.start(0, 'lua') vim.treesitter.start(0, 'lua')
vim.treesitter.inspect_tree() vim.treesitter.inspect_tree()
]]) end)
feed('a') feed('a')
expect_tree [[ expect_tree [[
@@ -67,11 +67,11 @@ describe('vim.treesitter.inspect_tree', function()
``` ```
]]) ]])
exec_lua([[ exec_lua(function()
vim.treesitter.start(0, 'markdown') vim.treesitter.start(0, 'markdown')
vim.treesitter.get_parser():parse() vim.treesitter.get_parser():parse()
vim.treesitter.inspect_tree() vim.treesitter.inspect_tree()
]]) end)
expect_tree [[ expect_tree [[
(document ; [0, 0] - [4, 0] (document ; [0, 0] - [4, 0]
@@ -96,11 +96,11 @@ describe('vim.treesitter.inspect_tree', function()
``` ```
]]) ]])
exec_lua([[ exec_lua(function()
vim.treesitter.start(0, 'markdown') vim.treesitter.start(0, 'markdown')
vim.treesitter.get_parser():parse() vim.treesitter.get_parser():parse()
vim.treesitter.inspect_tree() vim.treesitter.inspect_tree()
]]) end)
feed('I') feed('I')
expect_tree [[ expect_tree [[
@@ -125,28 +125,28 @@ describe('vim.treesitter.inspect_tree', function()
]]) ]])
-- setup two windows for the source buffer -- setup two windows for the source buffer
exec_lua([[ exec_lua(function()
source_win = vim.api.nvim_get_current_win() _G.source_win = vim.api.nvim_get_current_win()
vim.api.nvim_open_win(0, false, { vim.api.nvim_open_win(0, false, {
win = 0, win = 0,
split = 'left' split = 'left',
}) })
]]) end)
-- setup three windows for the tree buffer -- setup three windows for the tree buffer
exec_lua([[ exec_lua(function()
vim.treesitter.start(0, 'lua') vim.treesitter.start(0, 'lua')
vim.treesitter.inspect_tree() vim.treesitter.inspect_tree()
tree_win = vim.api.nvim_get_current_win() _G.tree_win = vim.api.nvim_get_current_win()
tree_win_copy_1 = vim.api.nvim_open_win(0, false, { _G.tree_win_copy_1 = vim.api.nvim_open_win(0, false, {
win = 0, win = 0,
split = 'left' split = 'left',
}) })
tree_win_copy_2 = vim.api.nvim_open_win(0, false, { _G.tree_win_copy_2 = vim.api.nvim_open_win(0, false, {
win = 0, win = 0,
split = 'left' split = 'left',
}) })
]]) end)
-- close original source window -- close original source window
exec_lua('vim.api.nvim_win_close(source_win, false)') exec_lua('vim.api.nvim_win_close(source_win, false)')

View File

@@ -54,10 +54,10 @@ describe('treesitter language API', function()
end) end)
it('inspects language', function() 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 lang = vim.treesitter.language.inspect('c')
local keys, symbols = {}, {} local keys, symbols = {}, {}
for k,_ in pairs(lang) do for k, _ in pairs(lang) do
keys[k] = true keys[k] = true
end end
@@ -66,8 +66,8 @@ describe('treesitter language API', function()
for _, v in pairs(lang.symbols) do for _, v in pairs(lang.symbols) do
table.insert(symbols, v) table.insert(symbols, v)
end 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 }, keys)
@@ -113,12 +113,14 @@ describe('treesitter language API', function()
int x = 3; int x = 3;
}]]) }]])
exec_lua([[ eq(
langtree = vim.treesitter.get_parser(0, "c") '<node translation_unit>',
tree = langtree:tree_for_range({1, 3, 1, 3}) exec_lua(function()
]]) local langtree = vim.treesitter.get_parser(0, 'c')
local tree = langtree:tree_for_range({ 1, 3, 1, 3 })
eq('<node translation_unit>', exec_lua('return tostring(tree:root())')) return tostring(tree:root())
end)
)
end) end)
it('retrieve the tree given a range when range is out of bounds relative to buffer', function() 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; int x = 3;
}]]) }]])
exec_lua([[ eq(
langtree = vim.treesitter.get_parser(0, "c") '<node translation_unit>',
tree = langtree:tree_for_range({10, 10, 10, 10}) exec_lua(function()
]]) local langtree = vim.treesitter.get_parser(0, 'c')
local tree = langtree:tree_for_range({ 10, 10, 10, 10 })
eq('<node translation_unit>', exec_lua('return tostring(tree:root())')) return tostring(tree:root())
end)
)
end) end)
it('retrieve the node given a range', function() it('retrieve the node given a range', function()
@@ -141,12 +145,14 @@ describe('treesitter language API', function()
int x = 3; int x = 3;
}]]) }]])
exec_lua([[ eq(
langtree = vim.treesitter.get_parser(0, "c") '<node primitive_type>',
node = langtree:named_node_for_range({1, 3, 1, 3}) exec_lua(function()
]]) local langtree = vim.treesitter.get_parser(0, 'c')
local node = langtree:named_node_for_range({ 1, 3, 1, 3 })
eq('<node primitive_type>', exec_lua('return tostring(node)')) return tostring(node)
end)
)
end) end)
it('retrieve an anonymous node given a range', function() it('retrieve an anonymous node given a range', function()

View File

@@ -18,39 +18,39 @@ describe('treesitter node API', function()
it('double free tree', function() it('double free tree', function()
insert('F') insert('F')
exec_lua([[ exec_lua(function()
vim.treesitter.start(0, 'lua') vim.treesitter.start(0, 'lua')
vim.treesitter.get_node():tree() vim.treesitter.get_node():tree()
vim.treesitter.get_node():tree() vim.treesitter.get_node():tree()
collectgarbage() collectgarbage()
]]) end)
assert_alive() assert_alive()
end) end)
it('double free tree 2', function() it('double free tree 2', function()
exec_lua([[ exec_lua(function()
parser = vim.treesitter.get_parser(0, "c") local parser = vim.treesitter.get_parser(0, 'c')
local x = parser:parse()[1]:root():tree() 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() 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() parser:parse()
collectgarbage() collectgarbage()
x:root() x:root()
]]) end)
assert_alive() assert_alive()
end) end)
it('get_node() with lang given', function() it('get_node() with lang given', function()
-- this buffer doesn't have filetype set! -- this buffer doesn't have filetype set!
insert('local foo = function() end') insert('local foo = function() end')
exec_lua([[ exec_lua(function()
node = vim.treesitter.get_node({ _G.node = vim.treesitter.get_node({
bufnr = 0, bufnr = 0,
pos = { 0, 6 }, -- on "foo" pos = { 0, 6 }, -- on "foo"
lang = 'lua', lang = 'lua',
}) })
]]) end)
eq('foo', lua_eval('vim.treesitter.get_node_text(node, 0)')) eq('foo', lua_eval('vim.treesitter.get_node_text(node, 0)'))
eq('identifier', lua_eval('node:type()')) eq('identifier', lua_eval('node:type()'))
end) end)
@@ -79,16 +79,16 @@ describe('treesitter node API', function()
} }
]]) ]])
exec_lua([[ exec_lua(function()
parser = vim.treesitter.get_parser(0, "c") local parser = vim.treesitter.get_parser(0, 'c')
tree = parser:parse()[1] local tree = parser:parse()[1]
root = tree:root() _G.root = tree:root()
lang = vim.treesitter.language.inspect('c') vim.treesitter.language.inspect('c')
function node_text(node) function _G.node_text(node)
return vim.treesitter.get_node_text(node, 0) return vim.treesitter.get_node_text(node, 0)
end end
]]) end)
exec_lua 'node = root:descendant_for_range(0, 11, 0, 16)' exec_lua 'node = root:descendant_for_range(0, 11, 0, 16)'
eq('int x', lua_eval('node_text(node)')) eq('int x', lua_eval('node_text(node)'))
@@ -118,13 +118,13 @@ describe('treesitter node API', function()
int x = 3; int x = 3;
}]]) }]])
local len = exec_lua([[ local len = exec_lua(function()
tree = vim.treesitter.get_parser(0, "c"):parse()[1] local tree = vim.treesitter.get_parser(0, 'c'):parse()[1]
node = tree:root():child(0) local node = tree:root():child(0)
children = node:named_children() _G.children = node:named_children()
return #children return #_G.children
]]) end)
eq(3, len) eq(3, len)
eq('<node compound_statement>', lua_eval('tostring(children[3])')) eq('<node compound_statement>', lua_eval('tostring(children[3])'))
@@ -136,11 +136,11 @@ describe('treesitter node API', function()
int x = 3; int x = 3;
}]]) }]])
exec_lua([[ exec_lua(function()
tree = vim.treesitter.get_parser(0, "c"):parse()[1] local tree = vim.treesitter.get_parser(0, 'c'):parse()[1]
root = tree:root() _G.root = tree:root()
node = root:child(0):child(2) _G.node = _G.root:child(0):child(2)
]]) end)
eq(lua_eval('tostring(root)'), lua_eval('tostring(node:root())')) eq(lua_eval('tostring(root)'), lua_eval('tostring(node:root())'))
end) end)
@@ -151,11 +151,11 @@ describe('treesitter node API', function()
int x = 3; int x = 3;
}]]) }]])
exec_lua([[ exec_lua(function()
tree = vim.treesitter.get_parser(0, "c"):parse()[1] local tree = vim.treesitter.get_parser(0, 'c'):parse()[1]
root = tree:root() _G.root = tree:root()
child = root:child(0):child(0) _G.child = _G.root:child(0):child(0)
]]) end)
eq(28, lua_eval('root:byte_length()')) eq(28, lua_eval('root:byte_length()'))
eq(3, lua_eval('child:byte_length()')) eq(3, lua_eval('child:byte_length()'))
@@ -167,15 +167,15 @@ describe('treesitter node API', function()
int x = 3; int x = 3;
}]]) }]])
exec_lua([[ exec_lua(function()
tree = vim.treesitter.get_parser(0, "c"):parse()[1] local tree = vim.treesitter.get_parser(0, 'c'):parse()[1]
root = tree:root() _G.root = tree:root()
main = root:child(0) _G.main = _G.root:child(0)
body = main:child(2) _G.body = _G.main:child(2)
statement = body:child(1) _G.statement = _G.body:child(1)
declarator = statement:child(1) _G.declarator = _G.statement:child(1)
value = declarator: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('main:type()'), lua_eval('root:child_containing_descendant(value):type()'))
eq(lua_eval('body:type()'), lua_eval('main:child_containing_descendant(value):type()')) eq(lua_eval('body:type()'), lua_eval('main:child_containing_descendant(value):type()'))

View File

@@ -12,9 +12,9 @@ local feed = n.feed
describe('treesitter parser API', function() describe('treesitter parser API', function()
before_each(function() before_each(function()
clear() clear()
exec_lua [[ exec_lua(function()
vim.g.__ts_debug = 1 vim.g.__ts_debug = 1
]] end)
end) end)
it('parses buffer', function() it('parses buffer', function()
@@ -23,12 +23,12 @@ describe('treesitter parser API', function()
int x = 3; int x = 3;
}]]) }]])
exec_lua([[ exec_lua(function()
parser = vim.treesitter.get_parser(0, "c") _G.parser = vim.treesitter.get_parser(0, 'c')
tree = parser:parse()[1] _G.tree = _G.parser:parse()[1]
root = tree:root() _G.root = _G.tree:root()
lang = vim.treesitter.language.inspect('c') _G.lang = vim.treesitter.language.inspect('c')
]]) end)
eq('<tree>', exec_lua('return tostring(tree)')) eq('<tree>', exec_lua('return tostring(tree)'))
eq('<node translation_unit>', exec_lua('return tostring(root)')) eq('<node translation_unit>', exec_lua('return tostring(root)'))
@@ -59,11 +59,11 @@ describe('treesitter parser API', function()
) )
feed('2G7|ay') feed('2G7|ay')
exec_lua([[ exec_lua(function()
tree2 = parser:parse()[1] _G.tree2 = _G.parser:parse()[1]
root2 = tree2:root() _G.root2 = _G.tree2:root()
descendant2 = root2:descendant_for_range(1,2,1,13) _G.descendant2 = _G.root2:descendant_for_range(1, 2, 1, 13)
]]) end)
eq(false, exec_lua('return tree2 == tree1')) eq(false, exec_lua('return tree2 == tree1'))
eq(false, exec_lua('return root2 == root')) eq(false, exec_lua('return root2 == root'))
eq('<node declaration>', exec_lua('return tostring(descendant2)')) eq('<node declaration>', exec_lua('return tostring(descendant2)'))
@@ -112,17 +112,17 @@ void ui_refresh(void)
it('allows to iterate over nodes children', function() it('allows to iterate over nodes children', function()
insert(test_text) insert(test_text)
local res = exec_lua([[ local res = exec_lua(function()
parser = vim.treesitter.get_parser(0, "c") 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 for node, field in func_node:iter_children() do
table.insert(res, { node:type(), field }) table.insert(res, { node:type(), field })
end end
return res return res
]]) end)
eq({ eq({
{ 'primitive_type', 'type' }, { 'primitive_type', 'type' },
@@ -148,43 +148,43 @@ void ui_refresh(void)
it('allows to get a child by field', function() it('allows to get a child by field', function()
insert(test_text) insert(test_text)
local res = exec_lua([[ local res = exec_lua(function()
parser = vim.treesitter.get_parser(0, "c") 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 = {} 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() }) table.insert(res, { node:type(), node:range() })
end end
return res return res
]]) end)
eq({ { 'primitive_type', 0, 0, 0, 4 } }, res) eq({ { 'primitive_type', 0, 0, 0, 4 } }, res)
local res_fail = exec_lua([[ local res_fail = exec_lua(function()
parser = vim.treesitter.get_parser(0, "c") vim.treesitter.get_parser(0, 'c')
return #func_node:field("foo") == 0 return #_G.func_node:field('foo') == 0
]]) end)
assert(res_fail) assert(res_fail)
end) end)
it('supports getting text of multiline node', function() it('supports getting text of multiline node', function()
insert(test_text) insert(test_text)
local res = exec_lua([[ local res = exec_lua(function()
local parser = vim.treesitter.get_parser(0, "c") local parser = vim.treesitter.get_parser(0, 'c')
local tree = parser:parse()[1] local tree = parser:parse()[1]
return vim.treesitter.get_node_text(tree:root(), 0) return vim.treesitter.get_node_text(tree:root(), 0)
]]) end)
eq(test_text, res) eq(test_text, res)
local res2 = exec_lua([[ local res2 = exec_lua(function()
local parser = vim.treesitter.get_parser(0, "c") local parser = vim.treesitter.get_parser(0, 'c')
local root = parser:parse()[1]:root() local root = parser:parse()[1]:root()
return vim.treesitter.get_node_text(root:child(0):child(0), 0) return vim.treesitter.get_node_text(root:child(0):child(0), 0)
]]) end)
eq('void', res2) eq('void', res2)
end) end)
@@ -196,7 +196,7 @@ end]]
insert(text) insert(text)
eq( eq(
'', '',
exec_lua [[ exec_lua(function()
local fake_node = {} local fake_node = {}
function fake_node:start() function fake_node:start()
return 3, 0, 23 return 3, 0, 23
@@ -211,7 +211,7 @@ end]]
return 3, 0, 3, 0 return 3, 0, 3, 0
end end
return vim.treesitter.get_node_text(fake_node, 0) return vim.treesitter.get_node_text(fake_node, 0)
]] end)
) )
end) end)
@@ -221,7 +221,7 @@ end]]
{} {}
```]] ```]]
insert(text) insert(text)
local result = exec_lua([[ local result = exec_lua(function()
local fake_node = {} local fake_node = {}
function fake_node:start() function fake_node:start()
return 1, 0, 7 return 1, 0, 7
@@ -233,38 +233,38 @@ end]]
return 1, 0, 1, 0 return 1, 0, 1, 0
end end
return vim.treesitter.get_node_text(fake_node, 0) == '' return vim.treesitter.get_node_text(fake_node, 0) == ''
]]) end)
eq(true, result) eq(true, result)
end) end)
it('allows to set simple ranges', function() it('allows to set simple ranges', function()
insert(test_text) insert(test_text)
local res = exec_lua [[ local res = exec_lua(function()
parser = vim.treesitter.get_parser(0, "c") _G.parser = vim.treesitter.get_parser(0, 'c')
return { parser:parse()[1]:root():range() } return { _G.parser:parse()[1]:root():range() }
]] end)
eq({ 0, 0, 19, 0 }, res) eq({ 0, 0, 19, 0 }, res)
-- The following sets the included ranges for the current parser -- 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) -- As stated here, this only includes the function (thus the whole buffer, without the last line)
local res2 = exec_lua [[ local res2 = exec_lua(function()
local root = parser:parse()[1]:root() local root = _G.parser:parse()[1]:root()
parser:set_included_regions({{root:child(0)}}) _G.parser:set_included_regions({ { root:child(0) } })
parser:invalidate() _G.parser:invalidate()
return { parser:parse(true)[1]:root():range() } return { _G.parser:parse(true)[1]:root():range() }
]] end)
eq({ 0, 0, 18, 1 }, res2) eq({ 0, 0, 18, 1 }, res2)
eq({ { { 0, 0, 0, 18, 1, 512 } } }, exec_lua [[ return parser:included_regions() ]]) eq({ { { 0, 0, 0, 18, 1, 512 } } }, exec_lua [[ return parser:included_regions() ]])
local range_tbl = exec_lua [[ local range_tbl = exec_lua(function()
parser:set_included_regions { { { 0, 0, 17, 1 } } } _G.parser:set_included_regions { { { 0, 0, 17, 1 } } }
parser:parse() _G.parser:parse()
return parser:included_regions() return _G.parser:included_regions()
]] end)
eq({ { { 0, 0, 0, 17, 1, 508 } } }, range_tbl) eq({ { { 0, 0, 0, 17, 1, 508 } } }, range_tbl)
end) end)
@@ -272,25 +272,25 @@ end]]
it('allows to set complex ranges', function() it('allows to set complex ranges', function()
insert(test_text) insert(test_text)
local res = exec_lua [[ local res = exec_lua(function()
parser = vim.treesitter.get_parser(0, "c") local parser = vim.treesitter.get_parser(0, 'c')
query = vim.treesitter.query.parse("c", "(declaration) @decl") local query = vim.treesitter.query.parse('c', '(declaration) @decl')
local nodes = {} local nodes = {}
for _, node in query:iter_captures(parser:parse()[1]:root(), 0) do for _, node in query:iter_captures(parser:parse()[1]:root(), 0) do
table.insert(nodes, node) table.insert(nodes, node)
end 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 = {} local res = {}
for i=0,(root:named_child_count() - 1) do for i = 0, (root:named_child_count() - 1) do
table.insert(res, { root:named_child(i):range() }) table.insert(res, { root:named_child(i):range() })
end end
return res return res
]] end)
eq({ eq({
{ 2, 2, 2, 40 }, { 2, 2, 2, 40 },
@@ -304,10 +304,10 @@ end]]
end) end)
it('allows to create string parsers', function() it('allows to create string parsers', function()
local ret = exec_lua [[ local ret = exec_lua(function()
local parser = vim.treesitter.get_string_parser("int foo = 42;", "c") local parser = vim.treesitter.get_string_parser('int foo = 42;', 'c')
return { parser:parse()[1]:root():range() } return { parser:parse()[1]:root():range() }
]] end)
eq({ 0, 0, 0, 13 }, ret) eq({ 0, 0, 0, 13 }, ret)
end) end)
@@ -318,33 +318,31 @@ end]]
int bar = 13; int bar = 13;
]] ]]
local ret = exec_lua( local ret = exec_lua(function(str)
[[ local parser = vim.treesitter.get_string_parser(str, 'c')
local str = ...
local parser = vim.treesitter.get_string_parser(str, "c")
local nodes = {} local nodes = {}
local query = vim.treesitter.query.parse("c", '((identifier) @id (#eq? @id "foo"))') local query = vim.treesitter.query.parse('c', '((identifier) @id (#eq? @id "foo"))')
for _, node in query:iter_captures(parser:parse()[1]:root(), str) do for _, node in query:iter_captures(parser:parse()[1]:root(), str) do
table.insert(nodes, { node:range() }) table.insert(nodes, { node:range() })
end end
return nodes return nodes
]], end, txt)
txt
)
eq({ { 0, 10, 0, 13 } }, ret) eq({ { 0, 10, 0, 13 } }, ret)
end) end)
describe('when creating a language tree', function() describe('when creating a language tree', function()
local function get_ranges() local function get_ranges()
return exec_lua [[ return exec_lua(function()
local result = {} 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 return result
]] end)
end end
before_each(function() before_each(function()
@@ -360,16 +358,17 @@ int x = INT_MAX;
describe('when parsing regions independently', function() describe('when parsing regions independently', function()
it('should inject a language', function() it('should inject a language', function()
exec_lua([[ exec_lua(function()
parser = vim.treesitter.get_parser(0, "c", { _G.parser = vim.treesitter.get_parser(0, 'c', {
injections = { injections = {
c = ( c = (
'(preproc_def (preproc_arg) @injection.content (#set! injection.language "c")) ' .. '(preproc_def (preproc_arg) @injection.content (#set! injection.language "c")) '
'(preproc_function_def value: (preproc_arg) @injection.content (#set! injection.language "c"))' .. '(preproc_function_def value: (preproc_arg) @injection.content (#set! injection.language "c"))'
) ),
}}) },
parser:parse(true) })
]]) _G.parser:parse(true)
end)
eq('table', exec_lua('return type(parser:children().c)')) eq('table', exec_lua('return type(parser:children().c)'))
eq(5, exec_lua('return #parser:children().c:trees()')) eq(5, exec_lua('return #parser:children().c:trees()'))
@@ -397,16 +396,17 @@ int x = INT_MAX;
describe('when parsing regions combined', function() describe('when parsing regions combined', function()
it('should inject a language', function() it('should inject a language', function()
exec_lua([[ exec_lua(function()
parser = vim.treesitter.get_parser(0, "c", { _G.parser = vim.treesitter.get_parser(0, 'c', {
injections = { injections = {
c = ( c = (
'(preproc_def (preproc_arg) @injection.content (#set! injection.language "c") (#set! injection.combined)) ' .. '(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))' .. '(preproc_function_def value: (preproc_arg) @injection.content (#set! injection.language "c") (#set! injection.combined))'
) ),
}}) },
parser:parse(true) })
]]) _G.parser:parse(true)
end)
eq('table', exec_lua('return type(parser:children().c)')) eq('table', exec_lua('return type(parser:children().c)'))
eq(2, exec_lua('return #parser:children().c:trees()')) eq(2, exec_lua('return #parser:children().c:trees()'))
@@ -447,16 +447,17 @@ int x = INT_MAX;
describe('when using injection.self', function() describe('when using injection.self', function()
it('should inject the source language', function() it('should inject the source language', function()
exec_lua([[ exec_lua(function()
parser = vim.treesitter.get_parser(0, "c", { _G.parser = vim.treesitter.get_parser(0, 'c', {
injections = { injections = {
c = ( c = (
'(preproc_def (preproc_arg) @injection.content (#set! injection.self)) ' .. '(preproc_def (preproc_arg) @injection.content (#set! injection.self)) '
'(preproc_function_def value: (preproc_arg) @injection.content (#set! injection.self))' .. '(preproc_function_def value: (preproc_arg) @injection.content (#set! injection.self))'
) ),
}}) },
parser:parse(true) })
]]) _G.parser:parse(true)
end)
eq('table', exec_lua('return type(parser:children().c)')) eq('table', exec_lua('return type(parser:children().c)'))
eq(5, exec_lua('return #parser:children().c:trees()')) eq(5, exec_lua('return #parser:children().c:trees()'))
@@ -484,16 +485,17 @@ int x = INT_MAX;
describe('when using the offset directive', function() describe('when using the offset directive', function()
it('should shift the range by the directive amount', function() it('should shift the range by the directive amount', function()
exec_lua([[ exec_lua(function()
parser = vim.treesitter.get_parser(0, "c", { _G.parser = vim.treesitter.get_parser(0, 'c', {
injections = { injections = {
c = ( c = (
'(preproc_def ((preproc_arg) @injection.content (#set! injection.language "c") (#offset! @injection.content 0 2 0 -1))) ' .. '(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"))' .. '(preproc_function_def value: (preproc_arg) @injection.content (#set! injection.language "c"))'
) ),
}}) },
parser:parse(true) })
]]) _G.parser:parse(true)
end)
eq('table', exec_lua('return type(parser:children().c)')) eq('table', exec_lua('return type(parser:children().c)'))
eq({ eq({
@@ -506,7 +508,7 @@ int x = INT_MAX;
}, get_ranges()) }, get_ranges())
end) end)
it('should list all directives', function() it('should list all directives', function()
local res_list = exec_lua [[ local res_list = exec_lua(function()
local query = vim.treesitter.query local query = vim.treesitter.query
local list = query.list_directives() local list = query.list_directives()
@@ -514,7 +516,7 @@ int x = INT_MAX;
table.sort(list) table.sort(list)
return list return list
]] end)
eq({ 'gsub!', 'offset!', 'set!', 'trim!' }, res_list) eq({ 'gsub!', 'offset!', 'set!', 'trim!' }, res_list)
end) end)
@@ -530,18 +532,18 @@ int x = INT_MAX;
end) end)
it('should return the correct language tree', function() it('should return the correct language tree', function()
local result = exec_lua([[ local result = exec_lua(function()
parser = vim.treesitter.get_parser(0, "c", { local parser = vim.treesitter.get_parser(0, 'c', {
injections = { 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) 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 return sub_tree == parser:children().c
]]) end)
eq(true, result) eq(true, result)
end) end)
@@ -555,23 +557,23 @@ print()
end) end)
it('ignores optional captures #23100', function() it('ignores optional captures #23100', function()
local result = exec_lua([[ local result = exec_lua(function()
parser = vim.treesitter.get_parser(0, "lua", { local parser = vim.treesitter.get_parser(0, 'lua', {
injections = { injections = {
lua = ( lua = (
'(function_call ' .. '(function_call '
'(arguments ' .. .. '(arguments '
'(string)? @injection.content ' .. .. '(string)? @injection.content '
'(number)? @injection.content ' .. .. '(number)? @injection.content '
'(#offset! @injection.content 0 1 0 -1) ' .. .. '(#offset! @injection.content 0 1 0 -1) '
'(#set! injection.language "c")))' .. '(#set! injection.language "c")))'
) ),
} },
}) })
parser:parse(true) parser:parse(true)
return parser:is_valid() return parser:is_valid()
]]) end)
eq(true, result) eq(true, result)
end) end)
@@ -584,18 +586,15 @@ print()
int x = 3; int x = 3;
]]) ]])
local result = exec_lua([[ local result = exec_lua(function()
local result local query =
vim.treesitter.query.parse('c', '((number_literal) @number (#set! "key" "value"))')
local parser = vim.treesitter.get_parser(0, 'c')
query = vim.treesitter.query.parse("c", '((number_literal) @number (#set! "key" "value"))') local _, _, metadata =
parser = vim.treesitter.get_parser(0, "c") query:iter_matches(parser:parse()[1]:root(), 0, 0, -1, { all = true })()
return metadata.key
for pattern, match, metadata in query:iter_matches(parser:parse()[1]:root(), 0, 0, -1, { all = true }) do end)
result = metadata.key
end
return result
]])
eq('value', result) eq('value', result)
end) end)
@@ -606,19 +605,18 @@ print()
int x = 3; int x = 3;
]]) ]])
local result = exec_lua([[ local result = exec_lua(function()
local query = vim.treesitter.query local query = vim.treesitter.query.parse(
local value '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"))') local _, _, metadata =
parser = vim.treesitter.get_parser(0, "c") query:iter_matches(parser:parse()[1]:root(), 0, 0, -1, { all = true })()
local _, nested_tbl = next(metadata)
for pattern, match, metadata in query:iter_matches(parser:parse()[1]:root(), 0, 0, -1, { all = true }) do return nested_tbl.key
for _, nested_tbl in pairs(metadata) do end)
return nested_tbl.key
end
end
]])
eq('value', result) eq('value', result)
end) end)
@@ -628,19 +626,18 @@ print()
int x = 3; int x = 3;
]]) ]])
local result = exec_lua([[ local result = exec_lua(function()
local query = vim.treesitter.query local query = vim.treesitter.query.parse(
local result 'c',
'((number_literal) @number (#set! @number "key" "value") (#set! @number "key2" "value2"))'
)
local parser = vim.treesitter.get_parser(0, 'c')
query = vim.treesitter.query.parse("c", '((number_literal) @number (#set! @number "key" "value") (#set! @number "key2" "value2"))') local _, _, metadata =
parser = vim.treesitter.get_parser(0, "c") query:iter_matches(parser:parse()[1]:root(), 0, 0, -1, { all = true })()
local _, nested_tbl = next(metadata)
for pattern, match, metadata in query:iter_matches(parser:parse()[1]:root(), 0, 0, -1, { all = true }) do return nested_tbl
for _, nested_tbl in pairs(metadata) do end)
return nested_tbl
end
end
]])
local expected = { local expected = {
['key'] = 'value', ['key'] = 'value',
['key2'] = 'value2', ['key2'] = 'value2',
@@ -663,24 +660,21 @@ print()
(function_definition) @function (function_definition) @function
]] ]]
exec_lua([[ exec_lua(function()
vim.treesitter.start(0, 'c') vim.treesitter.start(0, 'c')
]]) end)
local function run_query() local function run_query()
return exec_lua( return exec_lua(function(query_str)
[[ local query = vim.treesitter.query.parse('c', query_str)
local query = vim.treesitter.query.parse("c", ...) local parser = vim.treesitter.get_parser()
parser = vim.treesitter.get_parser() local tree = parser:parse()[1]
tree = parser:parse()[1] local res = {}
res = {} for id, node in query:iter_captures(tree:root()) do
for id, node in query:iter_captures(tree:root()) do table.insert(res, { query.captures[id], node:range() })
table.insert(res, {query.captures[id], node:range()}) end
end return res
return res end, query0)
]],
query0
)
end end
eq({ eq({
@@ -718,18 +712,15 @@ print()
]] ]]
]==] ]==]
local r = exec_lua( local r = exec_lua(function(src)
[[ local parser = vim.treesitter.get_string_parser(src, 'lua')
local parser = vim.treesitter.get_string_parser(..., 'lua') parser:parse(true)
parser:parse(true) local ranges = {}
local ranges = {} parser:for_each_tree(function(tstree, tree)
parser:for_each_tree(function(tstree, tree) ranges[tree:lang()] = { tstree:root():range(true) }
ranges[tree:lang()] = { tstree:root():range(true) } end)
end) return ranges
return ranges end, source)
]],
source
)
eq({ eq({
lua = { 0, 6, 6, 16, 4, 438 }, lua = { 0, 6, 6, 16, 4, 438 },
@@ -741,19 +732,14 @@ print()
-- the ranges but only provide a Range4. Strip the byte entries from the ranges and make sure -- the ranges but only provide a Range4. Strip the byte entries from the ranges and make sure
-- add_bytes() produces the same result. -- add_bytes() produces the same result.
local rb = exec_lua( local rb = exec_lua(function(r0, source0)
[[ local add_bytes = require('vim.treesitter._range').add_bytes
local r, source = ... for lang, range in pairs(r0) do
local add_bytes = require('vim.treesitter._range').add_bytes r0[lang] = { range[1], range[2], range[4], range[5] }
for lang, range in pairs(r) do r0[lang] = add_bytes(source0, r0[lang])
r[lang] = {range[1], range[2], range[4], range[5]} end
r[lang] = add_bytes(source, r[lang]) return r0
end end, r, source)
return r
]],
r,
source
)
eq(rb, r) eq(rb, r)
end) end)
@@ -766,25 +752,25 @@ print()
]] ]]
-- This is not a valid injection since (code) has children and include-children is not set -- This is not a valid injection since (code) has children and include-children is not set
exec_lua [[ exec_lua(function()
parser1 = require('vim.treesitter.languagetree').new(0, "vimdoc", { _G.parser1 = require('vim.treesitter.languagetree').new(0, 'vimdoc', {
injections = { 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())')) eq(0, exec_lua('return #vim.tbl_keys(parser1:children())'))
exec_lua [[ exec_lua(function()
parser2 = require('vim.treesitter.languagetree').new(0, "vimdoc", { _G.parser2 = require('vim.treesitter.languagetree').new(0, 'vimdoc', {
injections = { 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, exec_lua('return #vim.tbl_keys(parser2:children())'))
eq({ { { 1, 0, 21, 2, 0, 42 } } }, exec_lua('return parser2:children().lua:included_regions()')) eq({ { { 1, 0, 21, 2, 0, 42 } } }, exec_lua('return parser2:children().lua:included_regions()'))
@@ -821,46 +807,46 @@ print()
< <
]]) ]])
exec_lua [[ exec_lua(function()
parser = require('vim.treesitter.languagetree').new(0, "vimdoc", { _G.parser = require('vim.treesitter.languagetree').new(0, 'vimdoc', {
injections = { 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 --- Do not parse injections by default
eq( eq(
0, 0,
exec_lua [[ exec_lua(function()
parser:parse() _G.parser:parse()
return #vim.tbl_keys(parser:children()) return #vim.tbl_keys(_G.parser:children())
]] end)
) )
--- Only parse injections between lines 0, 2 --- Only parse injections between lines 0, 2
eq( eq(
1, 1,
exec_lua [[ exec_lua(function()
parser:parse({0, 2}) _G.parser:parse({ 0, 2 })
return #parser:children().lua:trees() return #_G.parser:children().lua:trees()
]] end)
) )
eq( eq(
2, 2,
exec_lua [[ exec_lua(function()
parser:parse({2, 6}) _G.parser:parse({ 2, 6 })
return #parser:children().lua:trees() return #_G.parser:children().lua:trees()
]] end)
) )
eq( eq(
7, 7,
exec_lua [[ exec_lua(function()
parser:parse(true) _G.parser:parse(true)
return #parser:children().lua:trees() return #_G.parser:children().lua:trees()
]] end)
) )
end) end)
@@ -876,13 +862,13 @@ print()
feed(':set ft=help<cr>') feed(':set ft=help<cr>')
exec_lua [[ exec_lua(function()
vim.treesitter.get_parser(0, "vimdoc", { vim.treesitter.get_parser(0, 'vimdoc', {
injections = { 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) end)
it('is valid excluding, invalid including children initially', function() it('is valid excluding, invalid including children initially', function()

View File

@@ -10,28 +10,26 @@ local pcall_err = t.pcall_err
local api = n.api local api = n.api
local fn = n.fn local fn = n.fn
local get_query_result_code = [[ local function get_query_result(query_text)
function get_query_result(query_text) local cquery = vim.treesitter.query.parse('c', query_text)
cquery = vim.treesitter.query.parse("c", query_text) local parser = vim.treesitter.get_parser(0, 'c')
parser = vim.treesitter.get_parser(0, "c") local tree = parser:parse()[1]
tree = parser:parse()[1] local res = {}
res = {} for cid, node in cquery:iter_captures(tree:root(), 0) do
for cid, node in cquery:iter_captures(tree:root(), 0) do -- can't transmit node over RPC. just check the name, range, and text
-- can't transmit node over RPC. just check the name, range, and text local text = vim.treesitter.get_node_text(node, 0)
local text = vim.treesitter.get_node_text(node, 0) local range = { node:range() }
local range = {node:range()} table.insert(res, { cquery.captures[cid], node:type(), range, text })
table.insert(res, { cquery.captures[cid], node:type(), range, text })
end
return res
end end
]] return res
end
describe('treesitter query API', function() describe('treesitter query API', function()
before_each(function() before_each(function()
clear() clear()
exec_lua [[ exec_lua(function()
vim.g.__ts_debug = 1 vim.g.__ts_debug = 1
]] end)
end) end)
local test_text = [[ local test_text = [[
@@ -71,9 +69,9 @@ void ui_refresh(void)
it('supports runtime queries', function() it('supports runtime queries', function()
---@type string[] ---@type string[]
local ret = exec_lua [[ local ret = exec_lua(function()
return vim.treesitter.query.get("c", "highlights").captures return vim.treesitter.query.get('c', 'highlights').captures
]] end)
-- see $VIMRUNTIME/queries/c/highlights.scm -- see $VIMRUNTIME/queries/c/highlights.scm
eq('variable', ret[1]) eq('variable', ret[1])
@@ -84,22 +82,17 @@ void ui_refresh(void)
local long_query = test_query:rep(100) local long_query = test_query:rep(100)
---@return number ---@return number
local function q(_n) local function q(_n)
return exec_lua( return exec_lua(function(query, n0)
[[ local before = vim.api.nvim__stats().ts_query_parse_count
local query, n = ... collectgarbage('stop')
local before = vim.api.nvim__stats().ts_query_parse_count for _ = 1, n0, 1 do
collectgarbage("stop") vim.treesitter.query.parse('c', query, n0)
for i=1, n, 1 do end
cquery = vim.treesitter.query.parse("c", ...) collectgarbage('restart')
end collectgarbage('collect')
collectgarbage("restart") local after = vim.api.nvim__stats().ts_query_parse_count
collectgarbage("collect") return after - before
local after = vim.api.nvim__stats().ts_query_parse_count end, long_query, _n)
return after - before
]],
long_query,
_n
)
end end
eq(1, q(1)) eq(1, q(1))
@@ -110,20 +103,17 @@ void ui_refresh(void)
it('supports query and iter by capture (iter_captures)', function() it('supports query and iter by capture (iter_captures)', function()
insert(test_text) insert(test_text)
local res = exec_lua( local res = exec_lua(function(test_query0)
[[ local cquery = vim.treesitter.query.parse('c', test_query0)
cquery = vim.treesitter.query.parse("c", ...) local parser = vim.treesitter.get_parser(0, 'c')
parser = vim.treesitter.get_parser(0, "c") local tree = parser:parse()[1]
tree = parser:parse()[1] local res = {}
res = {} for cid, node in cquery:iter_captures(tree:root(), 0, 7, 14) do
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
-- can't transmit node over RPC. just check the name and range table.insert(res, { '@' .. cquery.captures[cid], node:type(), node:range() })
table.insert(res, { '@' .. cquery.captures[cid], node:type(), node:range() }) end
end return res
return res end, test_query)
]],
test_query
)
eq({ eq({
{ '@type', 'primitive_type', 8, 2, 8, 6 }, -- bool { '@type', 'primitive_type', 8, 2, 8, 6 }, -- bool
@@ -143,26 +133,23 @@ void ui_refresh(void)
insert(test_text) insert(test_text)
---@type table ---@type table
local res = exec_lua( local res = exec_lua(function(test_query0)
[[ local cquery = vim.treesitter.query.parse('c', test_query0)
cquery = vim.treesitter.query.parse("c", ...) local parser = vim.treesitter.get_parser(0, 'c')
parser = vim.treesitter.get_parser(0, "c") local tree = parser:parse()[1]
tree = parser:parse()[1] local res = {}
res = {} for pattern, match in cquery:iter_matches(tree:root(), 0, 7, 14, { all = true }) do
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
-- can't transmit node over RPC. just check the name and range local mrepr = {}
local mrepr = {} for cid, nodes in pairs(match) do
for cid, nodes in pairs(match) do for _, node in ipairs(nodes) do
for _, node in ipairs(nodes) do table.insert(mrepr, { '@' .. cquery.captures[cid], node:type(), node:range() })
table.insert(mrepr, { '@' .. cquery.captures[cid], node:type(), node:range() })
end
end end
table.insert(res, { pattern, mrepr })
end end
return res table.insert(res, { pattern, mrepr })
]], end
test_query return res
) end, test_query)
eq({ eq({
{ 3, { { '@type', 'primitive_type', 8, 2, 8, 6 } } }, { 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() it('supports query and iter by capture for quantifiers', function()
insert(test_text) insert(test_text)
local res = exec_lua( local res = exec_lua(function()
[[ local cquery = vim.treesitter.query.parse(
cquery = vim.treesitter.query.parse("c", ...) 'c',
parser = vim.treesitter.get_parser(0, "c") '(expression_statement (assignment_expression (call_expression)))+ @funccall'
tree = parser:parse()[1] )
res = {} local parser = vim.treesitter.get_parser(0, 'c')
for cid, node in cquery:iter_captures(tree:root(), 0, 7, 14) do local tree = parser:parse()[1]
-- can't transmit node over RPC. just check the name and range local res = {}
table.insert(res, { '@' .. cquery.captures[cid], node:type(), node:range() }) for cid, node in cquery:iter_captures(tree:root(), 0, 7, 14) do
end -- can't transmit node over RPC. just check the name and range
return res table.insert(res, { '@' .. cquery.captures[cid], node:type(), node:range() })
]], end
'(expression_statement (assignment_expression (call_expression)))+ @funccall' return res
) end)
eq({ eq({
{ '@funccall', 'expression_statement', 11, 4, 11, 34 }, { '@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() it('supports query and iter by match for quantifiers', function()
insert(test_text) insert(test_text)
local res = exec_lua( local res = exec_lua(function()
[[ local cquery = vim.treesitter.query.parse(
cquery = vim.treesitter.query.parse("c", ...) 'c',
parser = vim.treesitter.get_parser(0, "c") '(expression_statement (assignment_expression (call_expression)))+ @funccall'
tree = parser:parse()[1] )
res = {} local parser = vim.treesitter.get_parser(0, 'c')
for pattern, match in cquery:iter_matches(tree:root(), 0, 7, 14, { all = true }) do local tree = parser:parse()[1]
-- can't transmit node over RPC. just check the name and range local res = {}
local mrepr = {} for pattern, match in cquery:iter_matches(tree:root(), 0, 7, 14, { all = true }) do
for cid, nodes in pairs(match) do -- can't transmit node over RPC. just check the name and range
for _, node in ipairs(nodes) do local mrepr = {}
table.insert(mrepr, { '@' .. cquery.captures[cid], node:type(), node:range() }) for cid, nodes in pairs(match) do
end for _, node in ipairs(nodes) do
table.insert(mrepr, { '@' .. cquery.captures[cid], node:type(), node:range() })
end end
table.insert(res, {pattern, mrepr})
end end
return res table.insert(res, { pattern, mrepr })
]], end
'(expression_statement (assignment_expression (call_expression)))+ @funccall' return res
) end, '(expression_statement (assignment_expression (call_expression)))+ @funccall')
eq({ eq({
{ {
@@ -265,26 +252,26 @@ void ui_refresh(void)
} }
]]) ]])
local res = exec_lua( local res = exec_lua(function()
[[ local cquery = vim.treesitter.query.parse(
cquery = vim.treesitter.query.parse("c", ...) 'c',
parser = vim.treesitter.get_parser(0, "c") '(expression_statement (assignment_expression (call_expression)))+ @funccall'
tree = parser:parse()[1] )
res = {} local parser = vim.treesitter.get_parser(0, 'c')
for pattern, match in cquery:iter_matches(tree:root(), 0, 7, 14, { all = true }) do local tree = parser:parse()[1]
-- can't transmit node over RPC. just check the name and range local res = {}
local mrepr = {} for pattern, match in cquery:iter_matches(tree:root(), 0, 7, 14, { all = true }) do
for cid, nodes in pairs(match) do -- can't transmit node over RPC. just check the name and range
for _, node in ipairs(nodes) do local mrepr = {}
table.insert(mrepr, { '@' .. cquery.captures[cid], node:type(), node:range() }) for cid, nodes in pairs(match) do
end for _, node in ipairs(nodes) do
table.insert(mrepr, { '@' .. cquery.captures[cid], node:type(), node:range() })
end end
table.insert(res, {pattern, mrepr})
end end
return res table.insert(res, { pattern, mrepr })
]], end
'(expression_statement (assignment_expression (call_expression)))+ @funccall' return res
) end)
eq({ eq({
{ {
@@ -308,18 +295,18 @@ void ui_refresh(void)
insert('char* astring = "\\n"; (1 + 1) * 2 != 2;') insert('char* astring = "\\n"; (1 + 1) * 2 != 2;')
---@type table ---@type table
local res = exec_lua([[ local res = exec_lua(function()
query = ( local query = (
'([_] @plus (#vim-match? @plus "^\\\\+$"))' .. '([_] @plus (#vim-match? @plus "^\\\\+$"))'
'([_] @times (#vim-match? @times "^\\\\*$"))' .. .. '([_] @times (#vim-match? @times "^\\\\*$"))'
'([_] @paren (#vim-match? @paren "^\\\\($"))' .. .. '([_] @paren (#vim-match? @paren "^\\\\($"))'
'([_] @escape (#vim-match? @escape "^\\\\\\\\n$"))' .. .. '([_] @escape (#vim-match? @escape "^\\\\\\\\n$"))'
'([_] @string (#vim-match? @string "^\\"\\\\\\\\n\\"$"))' .. '([_] @string (#vim-match? @string "^\\"\\\\\\\\n\\"$"))'
) )
cquery = vim.treesitter.query.parse("c", query) local cquery = vim.treesitter.query.parse('c', query)
parser = vim.treesitter.get_parser(0, "c") local parser = vim.treesitter.get_parser(0, 'c')
tree = parser:parse()[1] local tree = parser:parse()[1]
res = {} local res = {}
for pattern, match in cquery:iter_matches(tree:root(), 0, 0, -1, { all = true }) do for pattern, match in cquery:iter_matches(tree:root(), 0, 0, -1, { all = true }) do
-- can't transmit node over RPC. just check the name and range -- can't transmit node over RPC. just check the name and range
local mrepr = {} local mrepr = {}
@@ -331,7 +318,7 @@ void ui_refresh(void)
table.insert(res, { pattern, mrepr }) table.insert(res, { pattern, mrepr })
end end
return res return res
]]) end)
eq({ eq({
{ 2, { { '@times', '*', 0, 4, 0, 5 } } }, { 2, { { '@times', '*', 0, 4, 0, 5 } } },
@@ -362,10 +349,9 @@ void ui_refresh(void)
return 0; return 0;
} }
]]) ]])
exec_lua(get_query_result_code)
local res0 = exec_lua( local res0 = exec_lua(
[[return get_query_result(...)]], get_query_result,
[[((primitive_type) @c-keyword (#any-of? @c-keyword "int" "float"))]] [[((primitive_type) @c-keyword (#any-of? @c-keyword "int" "float"))]]
) )
eq({ eq({
@@ -374,7 +360,7 @@ void ui_refresh(void)
}, res0) }, res0)
local res1 = exec_lua( local res1 = exec_lua(
[[return get_query_result(...)]], get_query_result,
[[ [[
((string_literal) @fizzbuzz-strings (#any-of? @fizzbuzz-strings ((string_literal) @fizzbuzz-strings (#any-of? @fizzbuzz-strings
"\"number= %d FizzBuzz\\n\"" "\"number= %d FizzBuzz\\n\""
@@ -395,16 +381,15 @@ void ui_refresh(void)
int x = 123; int x = 123;
enum C { y = 124 }; enum C { y = 124 };
int main() { int z = 125; }]]) int main() { int z = 125; }]])
exec_lua(get_query_result_code)
local result = exec_lua( local result = exec_lua(
[[return get_query_result(...)]], get_query_result,
[[((number_literal) @literal (#has-ancestor? @literal "function_definition"))]] [[((number_literal) @literal (#has-ancestor? @literal "function_definition"))]]
) )
eq({ { 'literal', 'number_literal', { 2, 21, 2, 24 }, '125' } }, result) eq({ { 'literal', 'number_literal', { 2, 21, 2, 24 }, '125' } }, result)
result = exec_lua( result = exec_lua(
[[return get_query_result(...)]], get_query_result,
[[((number_literal) @literal (#has-ancestor? @literal "function_definition" "enum_specifier"))]] [[((number_literal) @literal (#has-ancestor? @literal "function_definition" "enum_specifier"))]]
) )
eq({ eq({
@@ -413,7 +398,7 @@ void ui_refresh(void)
}, result) }, result)
result = exec_lua( result = exec_lua(
[[return get_query_result(...)]], get_query_result,
[[((number_literal) @literal (#not-has-ancestor? @literal "enum_specifier"))]] [[((number_literal) @literal (#not-has-ancestor? @literal "enum_specifier"))]]
) )
eq({ eq({
@@ -425,11 +410,14 @@ void ui_refresh(void)
it('allows loading query with escaped quotes and capture them `#{lua,vim}-match`?', function() it('allows loading query with escaped quotes and capture them `#{lua,vim}-match`?', function()
insert('char* astring = "Hello World!";') insert('char* astring = "Hello World!";')
local res = exec_lua([[ local res = exec_lua(function()
cquery = vim.treesitter.query.parse("c", '([_] @quote (#vim-match? @quote "^\\"$")) ([_] @quote (#lua-match? @quote "^\\"$"))') local cquery = vim.treesitter.query.parse(
parser = vim.treesitter.get_parser(0, "c") 'c',
tree = parser:parse()[1] '([_] @quote (#vim-match? @quote "^\\"$")) ([_] @quote (#lua-match? @quote "^\\"$"))'
res = {} )
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, { all = true }) do for pattern, match in cquery:iter_matches(tree:root(), 0, 0, -1, { all = true }) do
-- can't transmit node over RPC. just check the name and range -- can't transmit node over RPC. just check the name and range
local mrepr = {} local mrepr = {}
@@ -441,7 +429,7 @@ void ui_refresh(void)
table.insert(res, { pattern, mrepr }) table.insert(res, { pattern, mrepr })
end end
return res return res
]]) end)
eq({ eq({
{ 1, { { '@quote', '"', 0, 16, 0, 17 } } }, { 1, { { '@quote', '"', 0, 16, 0, 17 } } },
@@ -461,70 +449,64 @@ void ui_refresh(void)
local custom_query = '((identifier) @main (#is-main? @main))' local custom_query = '((identifier) @main (#is-main? @main))'
do do
local res = exec_lua( local res = exec_lua(function(custom_query0)
[[ local query = vim.treesitter.query
local query = vim.treesitter.query
local function is_main(match, pattern, bufnr, predicate) local function is_main(match, _pattern, bufnr, predicate)
local nodes = match[ predicate[2] ] local nodes = match[predicate[2]]
for _, node in ipairs(nodes) do for _, node in ipairs(nodes) do
if vim.treesitter.get_node_text(node, bufnr) == 'main' then if vim.treesitter.get_node_text(node, bufnr) == 'main' then
return true return true
end
end end
return false
end 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 -- Time bomb: update this in 0.12
if vim.fn.has('nvim-0.12') == 1 then if vim.fn.has('nvim-0.12') == 1 then
return 'Update this test to remove this message and { all = true } from add_predicate' return 'Update this test to remove this message and { all = true } from add_predicate'
end end
query.add_predicate("is-main?", is_main, { all = true }) query.add_predicate('is-main?', is_main, { all = true })
local query = query.parse("c", ...) local query0 = query.parse('c', custom_query0)
local nodes = {} local nodes = {}
for _, node in query:iter_captures(parser:parse()[1]:root(), 0) do for _, node in query0:iter_captures(parser:parse()[1]:root(), 0) do
table.insert(nodes, {node:range()}) table.insert(nodes, { node:range() })
end end
return nodes return nodes
]], end, custom_query)
custom_query
)
eq({ { 0, 4, 0, 8 } }, res) eq({ { 0, 4, 0, 8 } }, res)
end end
-- Once with the old API. Remove this whole 'do' block in 0.12 -- Once with the old API. Remove this whole 'do' block in 0.12
do do
local res = exec_lua( local res = exec_lua(function(custom_query0)
[[ local query = vim.treesitter.query
local query = vim.treesitter.query
local function is_main(match, pattern, bufnr, predicate) local function is_main(match, _pattern, bufnr, predicate)
local node = match[ predicate[2] ] local node = match[predicate[2]]
return vim.treesitter.get_node_text(node, bufnr) == 'main' return vim.treesitter.get_node_text(node, bufnr) == 'main'
end 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, true)
local query = query.parse("c", ...) local query0 = query.parse('c', custom_query0)
local nodes = {} local nodes = {}
for _, node in query:iter_captures(parser:parse()[1]:root(), 0) do for _, node in query0:iter_captures(parser:parse()[1]:root(), 0) do
table.insert(nodes, {node:range()}) table.insert(nodes, { node:range() })
end end
return nodes return nodes
]], end, custom_query)
custom_query
)
-- Remove this 'do' block in 0.12 -- Remove this 'do' block in 0.12
eq(0, fn.has('nvim-0.12')) eq(0, fn.has('nvim-0.12'))
@@ -532,16 +514,16 @@ void ui_refresh(void)
end end
do do
local res = exec_lua [[ local res = exec_lua(function()
local query = vim.treesitter.query local query = vim.treesitter.query
local t = {} local r = {}
for _, v in ipairs(query.list_predicates()) do for _, v in ipairs(query.list_predicates()) do
t[v] = true r[v] = true
end end
return t return r
]] end)
eq(true, res['is-main?']) eq(true, res['is-main?'])
end end
@@ -560,18 +542,15 @@ void ui_refresh(void)
local function test(input, query) local function test(input, query)
api.nvim_buf_set_lines(0, 0, -1, true, vim.split(dedent(input), '\n')) api.nvim_buf_set_lines(0, 0, -1, true, vim.split(dedent(input), '\n'))
return exec_lua( return exec_lua(function(query_str)
[[ local parser = vim.treesitter.get_parser(0, 'lua')
local parser = vim.treesitter.get_parser(0, "lua") local query0 = vim.treesitter.query.parse('lua', query_str)
local query = vim.treesitter.query.parse("lua", ...) local nodes = {}
local nodes = {} for _, node in query0:iter_captures(parser:parse()[1]:root(), 0) do
for _, node in query:iter_captures(parser:parse()[1]:root(), 0) do nodes[#nodes + 1] = { node:range() }
nodes[#nodes+1] = { node:range() } end
end return nodes
return nodes end, query)
]],
query
)
end end
eq( eq(
@@ -638,23 +617,21 @@ void ui_refresh(void)
-- Comment -- 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 (((comment (comment_content))+) @bar
(#lua-match? @bar "Comment")) (#lua-match? @bar "Comment"))
]] ]]
)
local result = exec_lua( local nodes = {}
[[ for _, node in query:iter_captures(parser:parse()[1]:root(), 0) do
local parser = vim.treesitter.get_parser(0, "lua") nodes[#nodes + 1] = { node:range() }
local query = vim.treesitter.query.parse("lua", ...) end
local nodes = {} return nodes
for _, node in query:iter_captures(parser:parse()[1]:root(), 0) do end)
nodes[#nodes+1] = { node:range() }
end
return nodes
]],
query
)
eq({ eq({
{ 0, 2, 0, 12 }, { 0, 2, 0, 12 },
@@ -668,23 +645,20 @@ void ui_refresh(void)
eq(0, fn.has('nvim-0.12')) eq(0, fn.has('nvim-0.12'))
insert(test_text) insert(test_text)
local res = exec_lua( local res = exec_lua(function(test_query0)
[[ local cquery = vim.treesitter.query.parse('c', test_query0)
cquery = vim.treesitter.query.parse("c", ...) local parser = vim.treesitter.get_parser(0, 'c')
parser = vim.treesitter.get_parser(0, "c") local tree = parser:parse()[1]
tree = parser:parse()[1] local res = {}
res = {} for pattern, match in cquery:iter_matches(tree:root(), 0, 7, 14) do
for pattern, match in cquery:iter_matches(tree:root(), 0, 7, 14) do local mrepr = {}
local mrepr = {} for cid, node in pairs(match) do
for cid, node in pairs(match) do table.insert(mrepr, { '@' .. cquery.captures[cid], node:type(), node:range() })
table.insert(mrepr, { '@' .. cquery.captures[cid], node:type(), node:range() })
end
table.insert(res, { pattern, mrepr })
end end
return res table.insert(res, { pattern, mrepr })
]], end
test_query return res
) end, test_query)
eq({ eq({
{ 3, { { '@type', 'primitive_type', 8, 2, 8, 6 } } }, { 3, { { '@type', 'primitive_type', 8, 2, 8, 6 } } },
@@ -716,23 +690,19 @@ void ui_refresh(void)
int bar = 13; int bar = 13;
]] ]]
local ret = exec_lua( local ret = exec_lua(function(str)
[[ local parser = vim.treesitter.get_string_parser(str, 'c')
local str = ...
local parser = vim.treesitter.get_string_parser(str, "c")
local nodes = {} local nodes = {}
local query = vim.treesitter.query.parse("c", '((identifier) @foo)') local query = vim.treesitter.query.parse('c', '((identifier) @foo)')
local first_child = parser:parse()[1]:root():child(1) local first_child = parser:parse()[1]:root():child(1)
for _, node in query:iter_captures(first_child, str) do for _, node in query:iter_captures(first_child, str) do
table.insert(nodes, { node:range() }) table.insert(nodes, { node:range() })
end end
return nodes return nodes
]], end, txt)
txt
)
eq({ { 1, 10, 1, 13 } }, ret) eq({ { 1, 10, 1, 13 } }, ret)
end) end)
@@ -789,7 +759,10 @@ void ui_refresh(void)
const char *sql = "SELECT * FROM Students WHERE name = 'Robert'); DROP TABLE Students;--"; 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 (declaration
type: (_) type: (_)
declarator: (init_declarator declarator: (init_declarator
@@ -800,20 +773,15 @@ void ui_refresh(void)
(#set! injection.language "sql") (#set! injection.language "sql")
(#contains? @_id "sql")) (#contains? @_id "sql"))
]] ]]
)
local result = exec_lua( local parser = vim.treesitter.get_parser(0, 'c')
[=[
local query = vim.treesitter.query.parse("c", ...)
local parser = vim.treesitter.get_parser(0, "c")
local root = parser:parse()[1]:root() local root = parser:parse()[1]:root()
local t = {} local res = {}
for id, node, metadata in query:iter_captures(root, 0) do for id, _, metadata in query:iter_captures(root, 0) do
t[query.captures[id]] = metadata res[query.captures[id]] = metadata
end end
return t return res
]=], end)
query
)
eq({ eq({
['_id'] = { ['injection.language'] = 'sql' }, ['_id'] = { ['injection.language'] = 'sql' },
@@ -837,25 +805,22 @@ void ui_refresh(void)
(#eq? @function.name "foo")) (#eq? @function.name "foo"))
]] ]]
local result = exec_lua( local result = exec_lua(function(query_str)
[[ local query0 = vim.treesitter.query.parse('c', query_str)
local query = vim.treesitter.query.parse("c", ...) local match_preds = query0.match_preds
local match_preds = query.match_preds
local called = 0 local called = 0
function query:match_preds(...) function query0:match_preds(...)
called = called + 1 called = called + 1
return match_preds(self, ...) return match_preds(self, ...)
end end
local parser = vim.treesitter.get_parser(0, "c") local parser = vim.treesitter.get_parser(0, 'c')
local root = parser:parse()[1]:root() local root = parser:parse()[1]:root()
local captures = {} 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 captures[#captures + 1] = id
end end
return { called, captures } return { called, captures }
]], end, query)
query
)
eq({ 2, { 1, 1, 2, 2 } }, result) eq({ 2, { 1, 1, 2, 2 } }, result)
end) end)

View File

@@ -17,26 +17,26 @@ describe('treesitter utils', function()
int x = 3; int x = 3;
}]]) }]])
exec_lua([[ exec_lua(function()
parser = vim.treesitter.get_parser(0, "c") local parser = vim.treesitter.get_parser(0, 'c')
tree = parser:parse()[1] local tree = parser:parse()[1]
root = tree:root() local root = tree:root()
ancestor = root:child(0) _G.ancestor = root:child(0)
child = ancestor:child(0) _G.child = _G.ancestor:child(0)
]]) end)
eq(true, exec_lua('return vim.treesitter.is_ancestor(ancestor, child)')) eq(true, exec_lua('return vim.treesitter.is_ancestor(_G.ancestor, _G.child)'))
eq(false, exec_lua('return vim.treesitter.is_ancestor(child, ancestor)')) eq(false, exec_lua('return vim.treesitter.is_ancestor(_G.child, _G.ancestor)'))
end) end)
it('can detect if a position is contained in a node', function() it('can detect if a position is contained in a node', function()
exec_lua([[ exec_lua(function()
node = { _G.node = {
range = function() range = function()
return 0, 4, 0, 8 return 0, 4, 0, 8
end, end,
} }
]]) end)
eq(false, exec_lua('return vim.treesitter.is_in_node_range(node, 0, 3)')) eq(false, exec_lua('return vim.treesitter.is_in_node_range(node, 0, 3)'))
for i = 4, 7 do for i = 4, 7 do