mirror of
https://github.com/neovim/neovim.git
synced 2026-02-28 06:15:10 +00:00
Problem: :InspectTree don't show luadoc injection lua file. Since luadoc share the same "root" with comment in their common primary (lua) tree. Current logic simply show the largest (comment injection) and ignore all smaller one (luadoc injection). Solution: Handle different lang injections separately. Then sort them by byte_length to ensure the draw tree consistent.
311 lines
10 KiB
Lua
311 lines
10 KiB
Lua
local t = require('test.testutil')
|
|
local n = require('test.functional.testnvim')()
|
|
|
|
local clear = n.clear
|
|
local insert = n.insert
|
|
local dedent = t.dedent
|
|
local eq = t.eq
|
|
local exec_lua = n.exec_lua
|
|
local feed = n.feed
|
|
|
|
describe('vim.treesitter.inspect_tree', function()
|
|
before_each(clear)
|
|
|
|
local expect_tree = function(x)
|
|
local expected = vim.split(vim.trim(dedent(x)), '\n')
|
|
local actual = n.buf_lines(0) ---@type string[]
|
|
eq(expected, actual)
|
|
end
|
|
|
|
it('working', function()
|
|
insert([[
|
|
print()
|
|
]])
|
|
|
|
exec_lua(function()
|
|
vim.treesitter.start(0, 'lua')
|
|
vim.treesitter.inspect_tree()
|
|
end)
|
|
|
|
expect_tree [[
|
|
(chunk ; [0, 0] - [2, 0]
|
|
(function_call ; [0, 0] - [0, 7]
|
|
name: (identifier) ; [0, 0] - [0, 5]
|
|
arguments: (arguments))) ; [0, 5] - [0, 7]
|
|
]]
|
|
end)
|
|
|
|
it('sets correct buffer name', function()
|
|
t.skip(t.is_zig_build(), 'vim.treesitter not found after chdir with build.zig')
|
|
|
|
n.api.nvim_set_current_dir(t.paths.test_source_path .. '/test/functional/fixtures')
|
|
n.command('edit lua/syntax_error.lua')
|
|
eq('lua/syntax_error.lua', n.fn.bufname('%'))
|
|
local full_path = n.api.nvim_buf_get_name(0)
|
|
|
|
n.exec_lua('vim.treesitter.start(0, "lua")')
|
|
n.exec_lua('vim.treesitter.inspect_tree()')
|
|
local expected = [[
|
|
(chunk ; [0, 0] - [1, 0]
|
|
(ERROR ; [0, 0] - [0, 21]
|
|
(identifier) ; [0, 5] - [0, 8]
|
|
(identifier) ; [0, 9] - [0, 15]
|
|
(identifier))) ; [0, 16] - [0, 21]
|
|
]]
|
|
expect_tree(expected)
|
|
eq('Syntax tree for lua/syntax_error.lua', n.fn.bufname('%'))
|
|
|
|
n.command('bwipe!')
|
|
eq('lua/syntax_error.lua', n.fn.bufname('%'))
|
|
|
|
n.api.nvim_set_current_dir('pack')
|
|
eq(full_path, n.fn.bufname('%'))
|
|
|
|
n.exec_lua('vim.treesitter.inspect_tree()')
|
|
expect_tree(expected)
|
|
eq('Syntax tree for ' .. full_path, n.fn.bufname('%'))
|
|
end)
|
|
|
|
it('can toggle to show anonymous nodes', function()
|
|
insert([[
|
|
print('hello')
|
|
]])
|
|
|
|
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, 14]
|
|
name: (identifier) ; [0, 0] - [0, 5]
|
|
arguments: (arguments ; [0, 5] - [0, 14]
|
|
"(" ; [0, 5] - [0, 6]
|
|
(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)
|
|
|
|
it('works for injected trees', function()
|
|
insert([[
|
|
```lua
|
|
return
|
|
```
|
|
]])
|
|
|
|
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]
|
|
(section ; [0, 0] - [4, 0]
|
|
(fenced_code_block ; [0, 0] - [3, 0]
|
|
(fenced_code_block_delimiter) ; [0, 0] - [0, 3]
|
|
(info_string ; [0, 3] - [0, 6]
|
|
(language)) ; [0, 3] - [0, 6]
|
|
(block_continuation) ; [1, 0] - [1, 0]
|
|
(code_fence_content ; [1, 0] - [2, 0]
|
|
(chunk ; [1, 0] - [2, 0]
|
|
(return_statement)) ; [1, 0] - [1, 6]
|
|
(block_continuation)) ; [2, 0] - [2, 0]
|
|
(fenced_code_block_delimiter)))) ; [2, 0] - [2, 3]
|
|
]]
|
|
end)
|
|
|
|
it('works with multiple injection on the same node', function()
|
|
insert([[--* #include<stdio.h>]])
|
|
exec_lua(function()
|
|
vim.treesitter.query.set(
|
|
'lua',
|
|
'injections',
|
|
[[
|
|
(comment
|
|
content: (_) @injection.content
|
|
(#set! injection.language "markdown"))
|
|
(comment
|
|
content: (_) @injection.content
|
|
(#set! injection.language "c")
|
|
(#offset! @injection.content 0 1 0 0))
|
|
]]
|
|
)
|
|
vim.treesitter.start(0, 'lua')
|
|
vim.treesitter.get_parser():parse(true)
|
|
vim.treesitter.inspect_tree()
|
|
end)
|
|
feed('I')
|
|
expect_tree [[
|
|
(chunk ; [0, 0] - [1, 0] lua
|
|
(comment ; [0, 0] - [0, 21] lua
|
|
content: (comment_content ; [0, 2] - [0, 21] lua
|
|
(document ; [0, 2] - [0, 21] markdown
|
|
(section ; [0, 2] - [0, 21] markdown
|
|
(list ; [0, 2] - [0, 21] markdown
|
|
(list_item ; [0, 2] - [0, 21] markdown
|
|
(list_marker_star) ; [0, 2] - [0, 4] markdown
|
|
(paragraph ; [0, 4] - [0, 21] markdown
|
|
(inline ; [0, 4] - [0, 21] markdown
|
|
(inline))))))) ; [0, 4] - [0, 21] markdown_inline
|
|
(translation_unit ; [0, 4] - [0, 21] c
|
|
(preproc_include ; [0, 4] - [0, 21] c
|
|
path: (system_lib_string)))))) ; [0, 12] - [0, 21] c
|
|
]]
|
|
end)
|
|
|
|
it('can toggle to show languages', function()
|
|
insert([[
|
|
```lua
|
|
return
|
|
```
|
|
]])
|
|
|
|
exec_lua(function()
|
|
vim.treesitter.start(0, 'markdown')
|
|
vim.treesitter.get_parser():parse()
|
|
vim.treesitter.inspect_tree()
|
|
end)
|
|
feed('I')
|
|
|
|
expect_tree [[
|
|
(document ; [0, 0] - [4, 0] markdown
|
|
(section ; [0, 0] - [4, 0] markdown
|
|
(fenced_code_block ; [0, 0] - [3, 0] markdown
|
|
(fenced_code_block_delimiter) ; [0, 0] - [0, 3] markdown
|
|
(info_string ; [0, 3] - [0, 6] markdown
|
|
(language)) ; [0, 3] - [0, 6] markdown
|
|
(block_continuation) ; [1, 0] - [1, 0] markdown
|
|
(code_fence_content ; [1, 0] - [2, 0] markdown
|
|
(chunk ; [1, 0] - [2, 0] lua
|
|
(return_statement)) ; [1, 0] - [1, 6] lua
|
|
(block_continuation)) ; [2, 0] - [2, 0] markdown
|
|
(fenced_code_block_delimiter)))) ; [2, 0] - [2, 3] markdown
|
|
]]
|
|
end)
|
|
|
|
it('updates source and tree buffer windows and closes them correctly', function()
|
|
local name = t.tmpname()
|
|
n.command('edit ' .. name)
|
|
insert([[
|
|
print()
|
|
]])
|
|
n.command('set filetype=lua | write')
|
|
|
|
-- setup two windows for the source buffer
|
|
exec_lua(function()
|
|
_G.source_win = vim.api.nvim_get_current_win()
|
|
_G.source_win2 = vim.api.nvim_open_win(0, false, {
|
|
win = 0,
|
|
split = 'left',
|
|
})
|
|
end)
|
|
|
|
-- setup three windows for the tree buffer
|
|
exec_lua(function()
|
|
vim.treesitter.inspect_tree()
|
|
_G.tree_win = vim.api.nvim_get_current_win()
|
|
_G.tree_win2 = vim.api.nvim_open_win(0, false, {
|
|
win = 0,
|
|
split = 'left',
|
|
})
|
|
_G.tree_win3 = vim.api.nvim_open_win(0, false, {
|
|
win = 0,
|
|
split = 'left',
|
|
})
|
|
end)
|
|
|
|
-- close original source window without closing tree views
|
|
exec_lua('vim.api.nvim_set_current_win(source_win)')
|
|
feed(':quit<CR>')
|
|
eq('', n.api.nvim_get_vvar('errmsg'))
|
|
eq(true, exec_lua('return vim.api.nvim_win_is_valid(tree_win)'))
|
|
eq(true, exec_lua('return vim.api.nvim_win_is_valid(tree_win2)'))
|
|
eq(true, exec_lua('return vim.api.nvim_win_is_valid(tree_win3)'))
|
|
|
|
-- navigates correctly to the remaining source buffer window
|
|
exec_lua('vim.api.nvim_set_current_win(tree_win)')
|
|
feed('<CR>')
|
|
eq('', n.api.nvim_get_vvar('errmsg'))
|
|
eq(true, exec_lua('return vim.api.nvim_get_current_win() == source_win2'))
|
|
|
|
-- close original tree window
|
|
exec_lua(function()
|
|
vim.api.nvim_set_current_win(_G.tree_win2)
|
|
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'))
|
|
eq(true, exec_lua('return vim.api.nvim_get_current_win() == source_win2'))
|
|
|
|
-- close source buffer window and all remaining tree windows
|
|
n.expect_exit(n.command, 'quit')
|
|
end)
|
|
|
|
it('shows which nodes are missing', function()
|
|
insert([[
|
|
int main() {
|
|
if (a.) {
|
|
// ^ MISSING field_identifier here
|
|
if (1) d()
|
|
// ^ MISSING ";" here
|
|
}
|
|
}
|
|
]])
|
|
|
|
exec_lua(function()
|
|
vim.treesitter.start(0, 'c')
|
|
vim.treesitter.inspect_tree()
|
|
end)
|
|
feed('a')
|
|
|
|
expect_tree [[
|
|
(translation_unit ; [0, 0] - [8, 0]
|
|
(function_definition ; [0, 0] - [6, 1]
|
|
type: (primitive_type) ; [0, 0] - [0, 3]
|
|
declarator: (function_declarator ; [0, 4] - [0, 10]
|
|
declarator: (identifier) ; [0, 4] - [0, 8]
|
|
parameters: (parameter_list ; [0, 8] - [0, 10]
|
|
"(" ; [0, 8] - [0, 9]
|
|
")")) ; [0, 9] - [0, 10]
|
|
body: (compound_statement ; [0, 11] - [6, 1]
|
|
"{" ; [0, 11] - [0, 12]
|
|
(if_statement ; [1, 4] - [5, 5]
|
|
"if" ; [1, 4] - [1, 6]
|
|
condition: (parenthesized_expression ; [1, 7] - [1, 11]
|
|
"(" ; [1, 7] - [1, 8]
|
|
(field_expression ; [1, 8] - [1, 10]
|
|
argument: (identifier) ; [1, 8] - [1, 9]
|
|
operator: "." ; [1, 9] - [1, 10]
|
|
field: (MISSING field_identifier)) ; [1, 10] - [1, 10]
|
|
")") ; [1, 10] - [1, 11]
|
|
consequence: (compound_statement ; [1, 12] - [5, 5]
|
|
"{" ; [1, 12] - [1, 13]
|
|
(comment) ; [2, 4] - [2, 41]
|
|
(if_statement ; [3, 8] - [4, 36]
|
|
"if" ; [3, 8] - [3, 10]
|
|
condition: (parenthesized_expression ; [3, 11] - [3, 14]
|
|
"(" ; [3, 11] - [3, 12]
|
|
(number_literal) ; [3, 12] - [3, 13]
|
|
")") ; [3, 13] - [3, 14]
|
|
consequence: (expression_statement ; [3, 15] - [4, 36]
|
|
(call_expression ; [3, 15] - [3, 18]
|
|
function: (identifier) ; [3, 15] - [3, 16]
|
|
arguments: (argument_list ; [3, 16] - [3, 18]
|
|
"(" ; [3, 16] - [3, 17]
|
|
")")) ; [3, 17] - [3, 18]
|
|
(comment) ; [4, 8] - [4, 36]
|
|
(MISSING ";"))) ; [4, 36] - [4, 36]
|
|
"}")) ; [5, 4] - [5, 5]
|
|
"}"))) ; [6, 0] - [6, 1]
|
|
]]
|
|
end)
|
|
end)
|