neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

inspect_tree_spec.lua (10228B)


      1 local t = require('test.testutil')
      2 local n = require('test.functional.testnvim')()
      3 
      4 local clear = n.clear
      5 local insert = n.insert
      6 local dedent = t.dedent
      7 local eq = t.eq
      8 local exec_lua = n.exec_lua
      9 local feed = n.feed
     10 
     11 describe('vim.treesitter.inspect_tree', function()
     12  before_each(clear)
     13 
     14  local expect_tree = function(x)
     15    local expected = vim.split(vim.trim(dedent(x)), '\n')
     16    local actual = n.buf_lines(0) ---@type string[]
     17    eq(expected, actual)
     18  end
     19 
     20  it('working', function()
     21    insert([[
     22      print()
     23      ]])
     24 
     25    exec_lua(function()
     26      vim.treesitter.start(0, 'lua')
     27      vim.treesitter.inspect_tree()
     28    end)
     29 
     30    expect_tree [[
     31      (chunk ; [0, 0] - [2, 0]
     32        (function_call ; [0, 0] - [0, 7]
     33          name: (identifier) ; [0, 0] - [0, 5]
     34          arguments: (arguments))) ; [0, 5] - [0, 7]
     35      ]]
     36  end)
     37 
     38  it('sets correct buffer name', function()
     39    t.skip(t.is_zig_build(), 'vim.treesitter not found after chdir with build.zig')
     40 
     41    n.api.nvim_set_current_dir(t.paths.test_source_path .. '/test/functional/fixtures')
     42    n.command('edit lua/syntax_error.lua')
     43    eq('lua/syntax_error.lua', n.fn.bufname('%'))
     44    local full_path = n.api.nvim_buf_get_name(0)
     45 
     46    n.exec_lua('vim.treesitter.start(0, "lua")')
     47    n.exec_lua('vim.treesitter.inspect_tree()')
     48    local expected = [[
     49      (chunk ; [0, 0] - [1, 0]
     50        (ERROR ; [0, 0] - [0, 21]
     51          (identifier) ; [0, 5] - [0, 8]
     52          (identifier) ; [0, 9] - [0, 15]
     53          (identifier))) ; [0, 16] - [0, 21]
     54      ]]
     55    expect_tree(expected)
     56    eq('Syntax tree for lua/syntax_error.lua', n.fn.bufname('%'))
     57 
     58    n.command('bwipe!')
     59    eq('lua/syntax_error.lua', n.fn.bufname('%'))
     60 
     61    n.api.nvim_set_current_dir('pack')
     62    eq(full_path, n.fn.bufname('%'))
     63 
     64    n.exec_lua('vim.treesitter.inspect_tree()')
     65    expect_tree(expected)
     66    eq('Syntax tree for ' .. full_path, n.fn.bufname('%'))
     67  end)
     68 
     69  it('can toggle to show anonymous nodes', function()
     70    insert([[
     71      print('hello')
     72      ]])
     73 
     74    exec_lua(function()
     75      vim.treesitter.start(0, 'lua')
     76      vim.treesitter.inspect_tree()
     77    end)
     78    feed('a')
     79 
     80    expect_tree [[
     81      (chunk ; [0, 0] - [2, 0]
     82        (function_call ; [0, 0] - [0, 14]
     83          name: (identifier) ; [0, 0] - [0, 5]
     84          arguments: (arguments ; [0, 5] - [0, 14]
     85            "(" ; [0, 5] - [0, 6]
     86            (string ; [0, 6] - [0, 13]
     87              start: "'" ; [0, 6] - [0, 7]
     88              content: (string_content) ; [0, 7] - [0, 12]
     89              end: "'") ; [0, 12] - [0, 13]
     90            ")"))) ; [0, 13] - [0, 14]
     91      ]]
     92  end)
     93 
     94  it('works for injected trees', function()
     95    insert([[
     96      ```lua
     97      return
     98      ```
     99      ]])
    100 
    101    exec_lua(function()
    102      vim.treesitter.start(0, 'markdown')
    103      vim.treesitter.get_parser():parse()
    104      vim.treesitter.inspect_tree()
    105    end)
    106 
    107    expect_tree [[
    108      (document ; [0, 0] - [4, 0]
    109        (section ; [0, 0] - [4, 0]
    110          (fenced_code_block ; [0, 0] - [3, 0]
    111            (fenced_code_block_delimiter) ; [0, 0] - [0, 3]
    112            (info_string ; [0, 3] - [0, 6]
    113              (language)) ; [0, 3] - [0, 6]
    114            (block_continuation) ; [1, 0] - [1, 0]
    115            (code_fence_content ; [1, 0] - [2, 0]
    116              (chunk ; [1, 0] - [2, 0]
    117                (return_statement)) ; [1, 0] - [1, 6]
    118              (block_continuation)) ; [2, 0] - [2, 0]
    119            (fenced_code_block_delimiter)))) ; [2, 0] - [2, 3]
    120      ]]
    121  end)
    122 
    123  it('works with multiple injection on the same node', function()
    124    insert([[--* #include<stdio.h>]])
    125    exec_lua(function()
    126      vim.treesitter.query.set(
    127        'lua',
    128        'injections',
    129        [[
    130        (comment
    131          content: (_) @injection.content
    132          (#set! injection.language "markdown"))
    133        (comment
    134          content: (_) @injection.content
    135          (#set! injection.language "c")
    136          (#offset! @injection.content 0 1 0 0))
    137        ]]
    138      )
    139      vim.treesitter.start(0, 'lua')
    140      vim.treesitter.get_parser():parse(true)
    141      vim.treesitter.inspect_tree()
    142    end)
    143    feed('I')
    144    expect_tree [[
    145      (chunk ; [0, 0] - [1, 0] lua
    146        (comment ; [0, 0] - [0, 21] lua
    147          content: (comment_content ; [0, 2] - [0, 21] lua
    148            (document ; [0, 2] - [0, 21] markdown
    149              (section ; [0, 2] - [0, 21] markdown
    150                (list ; [0, 2] - [0, 21] markdown
    151                  (list_item ; [0, 2] - [0, 21] markdown
    152                    (list_marker_star) ; [0, 2] - [0, 4] markdown
    153                    (paragraph ; [0, 4] - [0, 21] markdown
    154                      (inline ; [0, 4] - [0, 21] markdown
    155                        (inline))))))) ; [0, 4] - [0, 21] markdown_inline
    156            (translation_unit ; [0, 4] - [0, 21] c
    157              (preproc_include ; [0, 4] - [0, 21] c
    158                path: (system_lib_string)))))) ; [0, 12] - [0, 21] c
    159    ]]
    160  end)
    161 
    162  it('can toggle to show languages', function()
    163    insert([[
    164      ```lua
    165      return
    166      ```
    167      ]])
    168 
    169    exec_lua(function()
    170      vim.treesitter.start(0, 'markdown')
    171      vim.treesitter.get_parser():parse()
    172      vim.treesitter.inspect_tree()
    173    end)
    174    feed('I')
    175 
    176    expect_tree [[
    177      (document ; [0, 0] - [4, 0] markdown
    178        (section ; [0, 0] - [4, 0] markdown
    179          (fenced_code_block ; [0, 0] - [3, 0] markdown
    180            (fenced_code_block_delimiter) ; [0, 0] - [0, 3] markdown
    181            (info_string ; [0, 3] - [0, 6] markdown
    182              (language)) ; [0, 3] - [0, 6] markdown
    183            (block_continuation) ; [1, 0] - [1, 0] markdown
    184            (code_fence_content ; [1, 0] - [2, 0] markdown
    185              (chunk ; [1, 0] - [2, 0] lua
    186                (return_statement)) ; [1, 0] - [1, 6] lua
    187              (block_continuation)) ; [2, 0] - [2, 0] markdown
    188            (fenced_code_block_delimiter)))) ; [2, 0] - [2, 3] markdown
    189      ]]
    190  end)
    191 
    192  it('updates source and tree buffer windows and closes them correctly', function()
    193    local name = t.tmpname()
    194    n.command('edit ' .. name)
    195    insert([[
    196      print()
    197      ]])
    198    n.command('set filetype=lua | write')
    199 
    200    -- setup two windows for the source buffer
    201    exec_lua(function()
    202      _G.source_win = vim.api.nvim_get_current_win()
    203      _G.source_win2 = vim.api.nvim_open_win(0, false, {
    204        win = 0,
    205        split = 'left',
    206      })
    207    end)
    208 
    209    -- setup three windows for the tree buffer
    210    exec_lua(function()
    211      vim.treesitter.inspect_tree()
    212      _G.tree_win = vim.api.nvim_get_current_win()
    213      _G.tree_win2 = vim.api.nvim_open_win(0, false, {
    214        win = 0,
    215        split = 'left',
    216      })
    217      _G.tree_win3 = vim.api.nvim_open_win(0, false, {
    218        win = 0,
    219        split = 'left',
    220      })
    221    end)
    222 
    223    -- close original source window without closing tree views
    224    exec_lua('vim.api.nvim_set_current_win(source_win)')
    225    feed(':quit<CR>')
    226    eq('', n.api.nvim_get_vvar('errmsg'))
    227    eq(true, exec_lua('return vim.api.nvim_win_is_valid(tree_win)'))
    228    eq(true, exec_lua('return vim.api.nvim_win_is_valid(tree_win2)'))
    229    eq(true, exec_lua('return vim.api.nvim_win_is_valid(tree_win3)'))
    230 
    231    -- navigates correctly to the remaining source buffer window
    232    exec_lua('vim.api.nvim_set_current_win(tree_win)')
    233    feed('<CR>')
    234    eq('', n.api.nvim_get_vvar('errmsg'))
    235    eq(true, exec_lua('return vim.api.nvim_get_current_win() == source_win2'))
    236 
    237    -- close original tree window
    238    exec_lua(function()
    239      vim.api.nvim_set_current_win(_G.tree_win2)
    240      vim.api.nvim_win_close(_G.tree_win, false)
    241    end)
    242 
    243    -- navigates correctly to the remaining source buffer window
    244    feed('<CR>')
    245    eq('', n.api.nvim_get_vvar('errmsg'))
    246    eq(true, exec_lua('return vim.api.nvim_get_current_win() == source_win2'))
    247 
    248    -- close source buffer window and all remaining tree windows
    249    n.expect_exit(n.command, 'quit')
    250  end)
    251 
    252  it('shows which nodes are missing', function()
    253    insert([[
    254      int main() {
    255          if (a.) {
    256          //    ^ MISSING field_identifier here
    257              if (1) d()
    258              //        ^ MISSING ";" here
    259          }
    260      }
    261      ]])
    262 
    263    exec_lua(function()
    264      vim.treesitter.start(0, 'c')
    265      vim.treesitter.inspect_tree()
    266    end)
    267    feed('a')
    268 
    269    expect_tree [[
    270      (translation_unit ; [0, 0] - [8, 0]
    271        (function_definition ; [0, 0] - [6, 1]
    272          type: (primitive_type) ; [0, 0] - [0, 3]
    273          declarator: (function_declarator ; [0, 4] - [0, 10]
    274            declarator: (identifier) ; [0, 4] - [0, 8]
    275            parameters: (parameter_list ; [0, 8] - [0, 10]
    276              "(" ; [0, 8] - [0, 9]
    277              ")")) ; [0, 9] - [0, 10]
    278          body: (compound_statement ; [0, 11] - [6, 1]
    279            "{" ; [0, 11] - [0, 12]
    280            (if_statement ; [1, 4] - [5, 5]
    281              "if" ; [1, 4] - [1, 6]
    282              condition: (parenthesized_expression ; [1, 7] - [1, 11]
    283                "(" ; [1, 7] - [1, 8]
    284                (field_expression ; [1, 8] - [1, 10]
    285                  argument: (identifier) ; [1, 8] - [1, 9]
    286                  operator: "." ; [1, 9] - [1, 10]
    287                  field: (MISSING field_identifier)) ; [1, 10] - [1, 10]
    288                ")") ; [1, 10] - [1, 11]
    289              consequence: (compound_statement ; [1, 12] - [5, 5]
    290                "{" ; [1, 12] - [1, 13]
    291                (comment) ; [2, 4] - [2, 41]
    292                (if_statement ; [3, 8] - [4, 36]
    293                  "if" ; [3, 8] - [3, 10]
    294                  condition: (parenthesized_expression ; [3, 11] - [3, 14]
    295                    "(" ; [3, 11] - [3, 12]
    296                    (number_literal) ; [3, 12] - [3, 13]
    297                    ")") ; [3, 13] - [3, 14]
    298                  consequence: (expression_statement ; [3, 15] - [4, 36]
    299                    (call_expression ; [3, 15] - [3, 18]
    300                      function: (identifier) ; [3, 15] - [3, 16]
    301                      arguments: (argument_list ; [3, 16] - [3, 18]
    302                        "(" ; [3, 16] - [3, 17]
    303                        ")")) ; [3, 17] - [3, 18]
    304                    (comment) ; [4, 8] - [4, 36]
    305                    (MISSING ";"))) ; [4, 36] - [4, 36]
    306                "}")) ; [5, 4] - [5, 5]
    307            "}"))) ; [6, 0] - [6, 1]
    308      ]]
    309  end)
    310 end)