neovim

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

parser_spec.lua (45681B)


      1 local t = require('test.testutil')
      2 local n = require('test.functional.testnvim')()
      3 local ts_t = require('test.functional.treesitter.testutil')
      4 
      5 local clear = n.clear
      6 local dedent = t.dedent
      7 local eq = t.eq
      8 local insert = n.insert
      9 local exec_lua = n.exec_lua
     10 local pcall_err = t.pcall_err
     11 local feed = n.feed
     12 local run_query = ts_t.run_query
     13 local assert_alive = n.assert_alive
     14 
     15 describe('treesitter parser API', function()
     16  before_each(function()
     17    clear()
     18    exec_lua(function()
     19      vim.g.__ts_debug = 1
     20    end)
     21  end)
     22 
     23  it('parses buffer', function()
     24    insert([[
     25      int main() {
     26        int x = 3;
     27      }]])
     28 
     29    exec_lua(function()
     30      _G.parser = vim.treesitter.get_parser(0, 'c')
     31      _G.tree = _G.parser:parse()[1]
     32      _G.root = _G.tree:root()
     33      _G.lang = vim.treesitter.language.inspect('c')
     34    end)
     35 
     36    eq('<tree>', exec_lua('return tostring(tree)'))
     37    eq('<node translation_unit>', exec_lua('return tostring(root)'))
     38    eq({ 0, 0, 3, 0 }, exec_lua('return {root:range()}'))
     39 
     40    eq(1, exec_lua('return root:child_count()'))
     41    exec_lua('child = root:child(0)')
     42    eq('<node function_definition>', exec_lua('return tostring(child)'))
     43    eq({ 0, 0, 2, 1 }, exec_lua('return {child:range()}'))
     44 
     45    eq('function_definition', exec_lua('return child:type()'))
     46    eq(true, exec_lua('return child:named()'))
     47    eq('number', type(exec_lua('return child:symbol()')))
     48    eq(true, exec_lua('return lang.symbols[child:type()]'))
     49 
     50    exec_lua('anon = root:descendant_for_range(0,8,0,9)')
     51    eq('(', exec_lua('return anon:type()'))
     52    eq(false, exec_lua('return anon:named()'))
     53    eq('number', type(exec_lua('return anon:symbol()')))
     54    eq(false, exec_lua([=[return lang.symbols[string.format('"%s"', anon:type())]]=]))
     55 
     56    exec_lua('descendant = root:descendant_for_range(1,2,1,12)')
     57    eq('<node declaration>', exec_lua('return tostring(descendant)'))
     58    eq({ 1, 2, 1, 12 }, exec_lua('return {descendant:range()}'))
     59    eq(
     60      '(declaration type: (primitive_type) declarator: (init_declarator declarator: (identifier) value: (number_literal)))',
     61      exec_lua('return descendant:sexpr()')
     62    )
     63 
     64    feed('2G7|ay')
     65    exec_lua(function()
     66      _G.tree2 = _G.parser:parse()[1]
     67      _G.root2 = _G.tree2:root()
     68      _G.descendant2 = _G.root2:descendant_for_range(1, 2, 1, 13)
     69    end)
     70    eq(false, exec_lua('return tree2 == tree1'))
     71    eq(false, exec_lua('return root2 == root'))
     72    eq('<node declaration>', exec_lua('return tostring(descendant2)'))
     73    eq({ 1, 2, 1, 13 }, exec_lua('return {descendant2:range()}'))
     74 
     75    eq(true, exec_lua('return child == child'))
     76    -- separate lua object, but represents same node
     77    eq(true, exec_lua('return child == root:child(0)'))
     78    eq(false, exec_lua('return child == descendant2'))
     79    eq(false, exec_lua('return child == nil'))
     80    eq(false, exec_lua('return child == tree'))
     81 
     82    eq('string', exec_lua('return type(child:id())'))
     83    eq(true, exec_lua('return child:id() == child:id()'))
     84    -- separate lua object, but represents same node
     85    eq(true, exec_lua('return child:id() == root:child(0):id()'))
     86    eq(false, exec_lua('return child:id() == descendant2:id()'))
     87    eq(false, exec_lua('return child:id() == nil'))
     88    eq(false, exec_lua('return child:id() == tree'))
     89 
     90    -- unchanged buffer: return the same tree
     91    eq(true, exec_lua('return parser:parse()[1] == tree2'))
     92  end)
     93 
     94  it('respects eol settings when parsing buffer', function()
     95    insert([[
     96      int main() {
     97        int x = 3;
     98      } // :D]])
     99 
    100    exec_lua(function()
    101      vim.bo.eol = false
    102      vim.bo.fixeol = false
    103      _G.parser = vim.treesitter.get_parser(0, 'c')
    104      _G.tree = _G.parser:parse()[1]
    105      _G.root = _G.tree:root()
    106      _G.lang = vim.treesitter.language.inspect('c')
    107    end)
    108 
    109    eq(
    110      '<node translation_unit>',
    111      exec_lua(function()
    112        return tostring(_G.root)
    113      end)
    114    )
    115    eq(
    116      { 0, 0, 0, 2, 7, 33 },
    117      exec_lua(function()
    118        return { _G.root:range(true) }
    119      end)
    120    )
    121 
    122    -- NOTE: Changing these settings marks the buffer as `modified` but does not fire `on_bytes`,
    123    -- meaning this test case does not pass... is this intended?
    124    -- exec_lua(function()
    125    --   vim.bo.eol = true
    126    --   vim.bo.fixeol = true
    127    --   vim.cmd.update()
    128    --   _G.parser = vim.treesitter.get_parser(0, 'c')
    129    --   _G.tree = _G.parser:parse()[1]
    130    --   _G.root = _G.tree:root()
    131    --   _G.lang = vim.treesitter.language.inspect('c')
    132    -- end)
    133    --
    134    -- eq(
    135    --   '<node translation_unit>',
    136    --   exec_lua(function()
    137    --     return tostring(root)
    138    --   end)
    139    -- )
    140    -- eq(
    141    --   { 0, 0, 0, 3, 0, 34 },
    142    --   exec_lua(function()
    143    --     return { root:range(true) }
    144    --   end)
    145    -- )
    146  end)
    147 
    148  it('parses buffer asynchronously', function()
    149    insert([[
    150      int main() {
    151        int x = 3;
    152      }]])
    153 
    154    exec_lua(function()
    155      _G.parser = vim.treesitter.get_parser(0, 'c')
    156      _G.lang = vim.treesitter.language.inspect('c')
    157      _G.parser:parse(nil, function(_, trees)
    158        _G.tree = trees[1]
    159        _G.root = _G.tree:root()
    160      end)
    161      vim.wait(100, function() end)
    162    end)
    163 
    164    eq('<tree>', exec_lua('return tostring(tree)'))
    165    eq('<node translation_unit>', exec_lua('return tostring(root)'))
    166    eq({ 0, 0, 3, 0 }, exec_lua('return {root:range()}'))
    167 
    168    eq(1, exec_lua('return root:child_count()'))
    169    exec_lua('child = root:child(0)')
    170    eq('<node function_definition>', exec_lua('return tostring(child)'))
    171    eq({ 0, 0, 2, 1 }, exec_lua('return {child:range()}'))
    172 
    173    eq('function_definition', exec_lua('return child:type()'))
    174    eq(true, exec_lua('return child:named()'))
    175    eq('number', type(exec_lua('return child:symbol()')))
    176    eq(true, exec_lua('return lang.symbols[child:type()]'))
    177 
    178    exec_lua('anon = root:descendant_for_range(0,8,0,9)')
    179    eq('(', exec_lua('return anon:type()'))
    180    eq(false, exec_lua('return anon:named()'))
    181    eq('number', type(exec_lua('return anon:symbol()')))
    182    eq(false, exec_lua([=[return lang.symbols[string.format('"%s"', anon:type())]]=]))
    183 
    184    exec_lua('descendant = root:descendant_for_range(1,2,1,12)')
    185    eq('<node declaration>', exec_lua('return tostring(descendant)'))
    186    eq({ 1, 2, 1, 12 }, exec_lua('return {descendant:range()}'))
    187    eq(
    188      '(declaration type: (primitive_type) declarator: (init_declarator declarator: (identifier) value: (number_literal)))',
    189      exec_lua('return descendant:sexpr()')
    190    )
    191 
    192    feed('2G7|ay')
    193    exec_lua(function()
    194      _G.parser:parse(nil, function(_, trees)
    195        _G.tree2 = trees[1]
    196        _G.root2 = _G.tree2:root()
    197        _G.descendant2 = _G.root2:descendant_for_range(1, 2, 1, 13)
    198      end)
    199      vim.wait(100, function() end)
    200    end)
    201    eq(false, exec_lua('return tree2 == tree1'))
    202    eq(false, exec_lua('return root2 == root'))
    203    eq('<node declaration>', exec_lua('return tostring(descendant2)'))
    204    eq({ 1, 2, 1, 13 }, exec_lua('return {descendant2:range()}'))
    205 
    206    eq(true, exec_lua('return child == child'))
    207    -- separate lua object, but represents same node
    208    eq(true, exec_lua('return child == root:child(0)'))
    209    eq(false, exec_lua('return child == descendant2'))
    210    eq(false, exec_lua('return child == nil'))
    211    eq(false, exec_lua('return child == tree'))
    212 
    213    eq('string', exec_lua('return type(child:id())'))
    214    eq(true, exec_lua('return child:id() == child:id()'))
    215    -- separate lua object, but represents same node
    216    eq(true, exec_lua('return child:id() == root:child(0):id()'))
    217    eq(false, exec_lua('return child:id() == descendant2:id()'))
    218    eq(false, exec_lua('return child:id() == nil'))
    219    eq(false, exec_lua('return child:id() == tree'))
    220 
    221    -- unchanged buffer: return the same tree
    222    eq(true, exec_lua('return parser:parse()[1] == tree2'))
    223  end)
    224 
    225  it('does not crash when editing large files', function()
    226    insert([[printf("%s", "some text");]])
    227    feed('yy49999p')
    228 
    229    exec_lua(function()
    230      _G.parser = vim.treesitter.get_parser(0, 'c')
    231      _G.done = false
    232      vim.treesitter.start(0, 'c')
    233      _G.parser:parse(nil, function()
    234        _G.done = true
    235      end)
    236      while not _G.done do
    237        -- Busy wait until async parsing has completed
    238        vim.wait(100, function() end)
    239      end
    240    end)
    241 
    242    eq(true, exec_lua([[return done]]))
    243    exec_lua(function()
    244      vim.api.nvim_input('Lxj')
    245    end)
    246    exec_lua(function()
    247      vim.api.nvim_input('xj')
    248    end)
    249    exec_lua(function()
    250      vim.api.nvim_input('xj')
    251    end)
    252    assert_alive()
    253  end)
    254 
    255  it('resets parsing state on tree changes', function()
    256    insert([[vim.api.nvim_set_hl(0, 'test2', { bg = 'green' })]])
    257    feed('yy1000p')
    258 
    259    exec_lua(function()
    260      vim.cmd('set ft=lua')
    261 
    262      vim.treesitter.start(0)
    263      local parser = assert(vim.treesitter.get_parser(0))
    264 
    265      parser:parse(true, function() end)
    266      vim.api.nvim_buf_set_lines(0, 1, -1, false, {})
    267      parser:parse(true)
    268    end)
    269  end)
    270 
    271  it('resets when buffer was editing during an async parse', function()
    272    insert([[printf("%s", "some text");]])
    273    feed('yy49999p')
    274    feed('gg4jO// Comment<Esc>')
    275 
    276    exec_lua(function()
    277      _G.parser = vim.treesitter.get_parser(0, 'c')
    278      _G.done = false
    279      vim.treesitter.start(0, 'c')
    280      _G.parser:parse(nil, function()
    281        _G.done = true
    282      end)
    283    end)
    284 
    285    exec_lua(function()
    286      vim.api.nvim_input('ggdj')
    287    end)
    288 
    289    eq(false, exec_lua([[return done]]))
    290    exec_lua(function()
    291      while not _G.done do
    292        -- Busy wait until async parsing finishes
    293        vim.wait(100, function() end)
    294      end
    295    end)
    296    eq(true, exec_lua([[return done]]))
    297    eq('comment', exec_lua([[return parser:parse()[1]:root():named_child(2):type()]]))
    298    eq({ 2, 0, 2, 10 }, exec_lua([[return {parser:parse()[1]:root():named_child(2):range()}]]))
    299  end)
    300 
    301  it('handles multiple async parse calls', function()
    302    insert([[printf("%s", "some text");]])
    303    feed('yy49999p')
    304 
    305    exec_lua(function()
    306      -- Spy on vim.schedule
    307      local schedule = vim.schedule
    308      vim.schedule = function(fn)
    309        _G.schedules = _G.schedules + 1
    310        schedule(fn)
    311      end
    312      _G.schedules = 0
    313      _G.parser = vim.treesitter.get_parser(0, 'c')
    314      for i = 1, 5 do
    315        _G['done' .. i] = false
    316        _G.parser:parse(nil, function()
    317          _G['done' .. i] = true
    318        end)
    319      end
    320      schedule(function()
    321        _G.schedules_snapshot = _G.schedules
    322      end)
    323    end)
    324 
    325    eq(2, exec_lua([[return schedules_snapshot]]))
    326    eq(
    327      { false, false, false, false, false },
    328      exec_lua([[return { done1, done2, done3, done4, done5 }]])
    329    )
    330    exec_lua(function()
    331      while not _G.done1 do
    332        -- Busy wait until async parsing finishes
    333        vim.wait(100, function() end)
    334      end
    335    end)
    336    eq({ true, true, true, true, true }, exec_lua([[return { done1, done2, done3, done4, done5 }]]))
    337  end)
    338 
    339  local test_text = [[
    340 void ui_refresh(void)
    341 {
    342  int width = INT_MAX, height = INT_MAX;
    343  bool ext_widgets[kUIExtCount];
    344  for (UIExtension i = 0; (int)i < kUIExtCount; i++) {
    345    ext_widgets[i] = true;
    346  }
    347 
    348  bool inclusive = ui_override();
    349  for (size_t i = 0; i < ui_count; i++) {
    350    UI *ui = uis[i];
    351    width = MIN(ui->width, width);
    352    height = MIN(ui->height, height);
    353    foo = BAR(ui->bazaar, bazaar);
    354    for (UIExtension j = 0; (int)j < kUIExtCount; j++) {
    355      ext_widgets[j] &= (ui->ui_ext[j] || inclusive);
    356    }
    357  }
    358 }]]
    359 
    360  it('can iterate over nodes children', function()
    361    insert(test_text)
    362 
    363    local res = exec_lua(function()
    364      local parser = vim.treesitter.get_parser(0, 'c')
    365 
    366      local func_node = parser:parse()[1]:root():child(0)
    367 
    368      local res = {}
    369      for node, field in func_node:iter_children() do
    370        table.insert(res, { node:type(), field })
    371      end
    372      return res
    373    end)
    374 
    375    eq({
    376      { 'primitive_type', 'type' },
    377      { 'function_declarator', 'declarator' },
    378      { 'compound_statement', 'body' },
    379    }, res)
    380  end)
    381 
    382  it('does not get parser for empty filetype', function()
    383    insert(test_text)
    384 
    385    eq(
    386      '.../treesitter.lua:0: Parser not found for buffer 1: language could not be determined',
    387      pcall_err(exec_lua, 'vim.treesitter.get_parser(0)')
    388    )
    389 
    390    -- Must provide language for buffers with an empty filetype
    391    exec_lua("vim.treesitter.get_parser(0, 'c')")
    392  end)
    393 
    394  it('can get a child by field', function()
    395    insert(test_text)
    396 
    397    local res = exec_lua(function()
    398      local parser = vim.treesitter.get_parser(0, 'c')
    399 
    400      _G.func_node = parser:parse()[1]:root():child(0)
    401 
    402      local res = {}
    403      for _, node in ipairs(_G.func_node:field('type')) do
    404        table.insert(res, { node:type(), node:range() })
    405      end
    406      return res
    407    end)
    408 
    409    eq({ { 'primitive_type', 0, 0, 0, 4 } }, res)
    410 
    411    local res_fail = exec_lua(function()
    412      vim.treesitter.get_parser(0, 'c')
    413 
    414      return #_G.func_node:field('foo') == 0
    415    end)
    416 
    417    assert(res_fail)
    418  end)
    419 
    420  it('can get text of multiline node', function()
    421    insert(test_text)
    422    local res = exec_lua(function()
    423      local parser = vim.treesitter.get_parser(0, 'c')
    424      local tree = parser:parse()[1]
    425      return vim.treesitter.get_node_text(tree:root(), 0)
    426    end)
    427    eq(test_text, res)
    428 
    429    local res2 = exec_lua(function()
    430      local parser = vim.treesitter.get_parser(0, 'c')
    431      local root = parser:parse()[1]:root()
    432      return vim.treesitter.get_node_text(root:child(0):child(0), 0)
    433    end)
    434    eq('void', res2)
    435  end)
    436 
    437  it('can get text where start of node is one past EOF', function()
    438    local text = [[
    439 def run
    440  a = <<~E
    441 end]]
    442    insert(text)
    443    eq(
    444      '',
    445      exec_lua(function()
    446        local fake_node = {}
    447        function fake_node:start()
    448          return 3, 0, 23
    449        end
    450        function fake_node:end_()
    451          return 3, 0, 23
    452        end
    453        function fake_node:range(bytes)
    454          if bytes then
    455            return 3, 0, 23, 3, 0, 23
    456          end
    457          return 3, 0, 3, 0
    458        end
    459        return vim.treesitter.get_node_text(fake_node, 0)
    460      end)
    461    )
    462  end)
    463 
    464  it('can get empty text if node range is zero-width', function()
    465    local text = [[
    466 ```lua
    467 {}
    468 ```]]
    469    insert(text)
    470    local result = exec_lua(function()
    471      local fake_node = {}
    472      function fake_node:start()
    473        return 1, 0, 7
    474      end
    475      function fake_node:end_()
    476        return 1, 0, 7
    477      end
    478      function fake_node:range()
    479        return 1, 0, 1, 0
    480      end
    481      return vim.treesitter.get_node_text(fake_node, 0) == ''
    482    end)
    483    eq(true, result)
    484  end)
    485 
    486  it('can set simple ranges', function()
    487    insert(test_text)
    488 
    489    local res = exec_lua(function()
    490      _G.parser = vim.treesitter.get_parser(0, 'c')
    491      return { _G.parser:parse()[1]:root():range() }
    492    end)
    493 
    494    eq({ 0, 0, 19, 0 }, res)
    495 
    496    -- The following sets the included ranges for the current parser
    497    -- As stated here, this only includes the function (thus the whole buffer, without the last line)
    498    local res2 = exec_lua(function()
    499      local root = _G.parser:parse()[1]:root()
    500      _G.parser:set_included_regions({ { root:child(0) } })
    501      _G.parser:invalidate()
    502      return { _G.parser:parse(true)[1]:root():range() }
    503    end)
    504 
    505    eq({ 0, 0, 18, 1 }, res2)
    506 
    507    eq({ { { 0, 0, 0, 18, 1, 512 } } }, exec_lua [[ return parser:included_regions() ]])
    508 
    509    local range_tbl = exec_lua(function()
    510      _G.parser:set_included_regions { { { 0, 0, 17, 1 } } }
    511      _G.parser:parse()
    512      return _G.parser:included_regions()
    513    end)
    514 
    515    eq({ { { 0, 0, 0, 17, 1, 508 } } }, range_tbl)
    516  end)
    517 
    518  it('can set complex ranges', function()
    519    insert(test_text)
    520 
    521    local res = exec_lua(function()
    522      local parser = vim.treesitter.get_parser(0, 'c')
    523      local query = vim.treesitter.query.parse('c', '(declaration) @decl')
    524 
    525      local nodes = {}
    526      for _, node in query:iter_captures(parser:parse()[1]:root(), 0) do
    527        table.insert(nodes, node)
    528      end
    529 
    530      parser:set_included_regions({ nodes })
    531 
    532      local root = parser:parse(true)[1]:root()
    533 
    534      local res = {}
    535      for i = 0, (root:named_child_count() - 1) do
    536        table.insert(res, { root:named_child(i):range() })
    537      end
    538      return res
    539    end)
    540 
    541    eq({
    542      { 2, 2, 2, 40 },
    543      { 3, 2, 3, 32 },
    544      { 4, 7, 4, 25 },
    545      { 8, 2, 8, 33 },
    546      { 9, 7, 9, 20 },
    547      { 10, 4, 10, 20 },
    548      { 14, 9, 14, 27 },
    549    }, res)
    550  end)
    551 
    552  it('can create string parsers', function()
    553    local ret = exec_lua(function()
    554      local parser = vim.treesitter.get_string_parser('int foo = 42;', 'c')
    555      return { parser:parse()[1]:root():range() }
    556    end)
    557 
    558    eq({ 0, 0, 0, 13 }, ret)
    559  end)
    560 
    561  it('can run async parses with string parsers', function()
    562    local ret = exec_lua(function()
    563      local parser = vim.treesitter.get_string_parser('int foo = 42;', 'c')
    564      return { parser:parse(nil, function() end)[1]:root():range() }
    565    end)
    566 
    567    eq({ 0, 0, 0, 13 }, ret)
    568  end)
    569 
    570  it('can run queries with string parsers', function()
    571    local txt = [[
    572      int foo = 42;
    573      int bar = 13;
    574    ]]
    575 
    576    local ret = exec_lua(function(str)
    577      local parser = vim.treesitter.get_string_parser(str, 'c')
    578 
    579      local nodes = {}
    580      local query = vim.treesitter.query.parse('c', '((identifier) @id (#eq? @id "foo"))')
    581 
    582      for _, node in query:iter_captures(parser:parse()[1]:root(), str) do
    583        table.insert(nodes, { node:range() })
    584      end
    585 
    586      return nodes
    587    end, txt)
    588 
    589    eq({ { 0, 10, 0, 13 } }, ret)
    590  end)
    591 
    592  describe('creating a language tree', function()
    593    local function get_ranges()
    594      return exec_lua(function()
    595        local result = {}
    596        _G.parser:for_each_tree(function(tree)
    597          table.insert(result, { tree:root():range() })
    598        end)
    599        return result
    600      end)
    601    end
    602 
    603    before_each(function()
    604      insert([[
    605 int x = INT_MAX;
    606 #define READ_STRING(x, y) (char *)read_string((x), (size_t)(y))
    607 #define READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y))
    608 #define VALUE 123
    609 #define VALUE1 123
    610 #define VALUE2 123
    611      ]])
    612    end)
    613 
    614    describe('parsing regions independently', function()
    615      it('injects a language', function()
    616        exec_lua(function()
    617          _G.parser = vim.treesitter.get_parser(0, 'c', {
    618            injections = {
    619              c = (
    620                '(preproc_def (preproc_arg) @injection.content (#set! injection.language "c")) '
    621                .. '(preproc_function_def value: (preproc_arg) @injection.content (#set! injection.language "c"))'
    622              ),
    623            },
    624          })
    625          _G.parser:parse(true)
    626        end)
    627 
    628        eq('table', exec_lua('return type(parser:children().c)'))
    629        eq(5, exec_lua('return #parser:children().c:trees()'))
    630        eq({
    631          { 0, 0, 7, 0 }, -- root tree
    632          { 1, 26, 1, 63 }, -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y))
    633          { 2, 29, 2, 66 }, -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y))
    634          { 3, 14, 3, 17 }, -- VALUE 123
    635          { 4, 15, 4, 18 }, -- VALUE1 123
    636          { 5, 15, 5, 18 }, -- VALUE2 123
    637        }, get_ranges())
    638 
    639        n.feed('ggo<esc>')
    640        eq(5, exec_lua('return #parser:children().c:trees()'))
    641        eq({
    642          { 0, 0, 8, 0 }, -- root tree
    643          { 2, 26, 2, 63 }, -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y))
    644          { 3, 29, 3, 66 }, -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y))
    645          { 4, 14, 4, 17 }, -- VALUE 123
    646          { 5, 15, 5, 18 }, -- VALUE1 123
    647          { 6, 15, 6, 18 }, -- VALUE2 123
    648        }, get_ranges())
    649      end)
    650    end)
    651 
    652    describe('when parsing regions combined', function()
    653      it('injects a language', function()
    654        exec_lua(function()
    655          _G.parser = vim.treesitter.get_parser(0, 'c', {
    656            injections = {
    657              c = (
    658                '(preproc_def (preproc_arg) @injection.content (#set! injection.language "c") (#set! injection.combined)) '
    659                .. '(preproc_function_def value: (preproc_arg) @injection.content (#set! injection.language "c") (#set! injection.combined))'
    660              ),
    661            },
    662          })
    663          _G.parser:parse(true)
    664        end)
    665 
    666        eq('table', exec_lua('return type(parser:children().c)'))
    667        eq(2, exec_lua('return #parser:children().c:trees()'))
    668        eq({
    669          { 0, 0, 7, 0 }, -- root tree
    670          { 1, 26, 2, 66 }, -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y))
    671          -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y))
    672          { 3, 14, 5, 18 }, -- VALUE 123
    673          -- VALUE1 123
    674          -- VALUE2 123
    675        }, get_ranges())
    676 
    677        n.feed('ggo<esc>')
    678        eq('table', exec_lua('return type(parser:children().c)'))
    679        eq(2, exec_lua('return #parser:children().c:trees()'))
    680        eq({
    681          { 0, 0, 8, 0 }, -- root tree
    682          { 2, 26, 3, 66 }, -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y))
    683          -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y))
    684          -- VALUE 123
    685          { 4, 14, 6, 18 }, -- VALUE1 123
    686          -- VALUE2 123
    687        }, get_ranges())
    688 
    689        n.feed('7ggI//<esc>')
    690        exec_lua([[parser:parse(true)]])
    691        eq('table', exec_lua('return type(parser:children().c)'))
    692        eq(2, exec_lua('return #parser:children().c:trees()'))
    693        eq({
    694          { 0, 0, 8, 0 }, -- root tree
    695          { 2, 26, 3, 66 }, -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y))
    696          -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y))
    697          -- VALUE 123
    698          { 4, 14, 5, 18 }, -- VALUE1 123
    699        }, get_ranges())
    700      end)
    701 
    702      it('scopes injections appropriately', function()
    703        -- `injection.combined` are combined within a TSTree.
    704        -- Lua injections on lines 2-4 should be combined within their
    705        -- respective C injection trees, and lua injections on lines 0 and 6
    706        -- are separate from each other and other lua injections on lines 2-4.
    707 
    708        exec_lua(function()
    709          local lines = {
    710            [[func('int a = func("local a = [=[");')]],
    711            [[]],
    712            [[func('int a = func("local a = 6") + func("+ 3");')]],
    713            [[func('int a = func("local a = 6") + func("+ 3");')]],
    714            [[func('int a = func("local a = 6") + func("+ 3");')]],
    715            [[]],
    716            [[func('int a = func("]=]");')]],
    717          }
    718          vim.api.nvim_buf_set_lines(0, 0, -1, true, lines)
    719          _G.parser = vim.treesitter.get_parser(0, 'lua', {
    720            injections = {
    721              lua = [[
    722                ((function_call
    723                  arguments: (arguments
    724                    (string (string_content) @injection.content)))
    725                  (#set! injection.language "c"))
    726              ]],
    727              c = [[
    728                ((call_expression
    729                  arguments: (argument_list
    730                    (string_literal (string_content) @injection.content)))
    731                  (#set! injection.combined)
    732                  (#set! injection.language "lua"))
    733              ]],
    734            },
    735          })
    736 
    737          function _G.langtree_regions(parser)
    738            local result_regions = {}
    739 
    740            local regions = parser:included_regions()
    741            for region_i, region in pairs(regions) do
    742              local result_region = {}
    743 
    744              for _, range in ipairs(region) do
    745                table.insert(result_region, {
    746                  range[1],
    747                  range[2],
    748                  range[4],
    749                  range[5],
    750                })
    751              end
    752 
    753              result_regions[region_i] = result_region
    754            end
    755 
    756            return result_regions
    757          end
    758          function _G.all_regions(parser)
    759            local this_regions = _G.langtree_regions(parser)
    760            local child_regions = {}
    761            for lang, child in pairs(parser:children()) do
    762              child_regions[lang] = _G.all_regions(child)
    763            end
    764            return { regions = this_regions, children = child_regions }
    765          end
    766        end)
    767 
    768        local expected_regions = {
    769          children = {}, -- nothing is parsed
    770          regions = {
    771            {}, -- root tree's regions is the entire buffer
    772          },
    773        }
    774        eq(expected_regions, exec_lua('return all_regions(_G.parser)'))
    775 
    776        exec_lua('_G.parser:parse({ 3, 0, 3, 45 })')
    777 
    778        expected_regions = {
    779          children = {
    780            c = {
    781              children = {
    782                lua = {
    783                  children = {},
    784                  regions = {
    785                    { { 3, 20, 3, 31 }, { 3, 42, 3, 45 } },
    786                  },
    787                },
    788              },
    789              regions = {
    790                { { 3, 6, 3, 48 } },
    791              },
    792            },
    793          },
    794          regions = {
    795            {},
    796          },
    797        }
    798        eq(expected_regions, exec_lua('return all_regions(_G.parser)'))
    799 
    800        exec_lua('_G.parser:parse(true)')
    801        expected_regions = {
    802          children = {
    803            c = {
    804              children = {
    805                lua = {
    806                  children = {},
    807                  regions = {
    808                    { { 0, 20, 0, 33 } },
    809                    { { 2, 20, 2, 31 }, { 2, 42, 2, 45 } },
    810                    { { 3, 20, 3, 31 }, { 3, 42, 3, 45 } },
    811                    { { 4, 20, 4, 31 }, { 4, 42, 4, 45 } },
    812                    { { 6, 20, 6, 23 } },
    813                  },
    814                },
    815              },
    816              regions = {
    817                { { 0, 6, 0, 36 } },
    818                { { 2, 6, 2, 48 } },
    819                { { 3, 6, 3, 48 } },
    820                { { 4, 6, 4, 48 } },
    821                { { 6, 6, 6, 26 } },
    822              },
    823            },
    824          },
    825          regions = {
    826            {},
    827          },
    828        }
    829        eq(expected_regions, exec_lua('return all_regions(_G.parser)'))
    830      end)
    831    end)
    832 
    833    describe('when using injection.self', function()
    834      it('injects the source language', function()
    835        exec_lua(function()
    836          _G.parser = vim.treesitter.get_parser(0, 'c', {
    837            injections = {
    838              c = (
    839                '(preproc_def (preproc_arg) @injection.content (#set! injection.self)) '
    840                .. '(preproc_function_def value: (preproc_arg) @injection.content (#set! injection.self))'
    841              ),
    842            },
    843          })
    844          _G.parser:parse(true)
    845        end)
    846 
    847        eq('table', exec_lua('return type(parser:children().c)'))
    848        eq(5, exec_lua('return #parser:children().c:trees()'))
    849        eq({
    850          { 0, 0, 7, 0 }, -- root tree
    851          { 1, 26, 1, 63 }, -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y))
    852          { 2, 29, 2, 66 }, -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y))
    853          { 3, 14, 3, 17 }, -- VALUE 123
    854          { 4, 15, 4, 18 }, -- VALUE1 123
    855          { 5, 15, 5, 18 }, -- VALUE2 123
    856        }, get_ranges())
    857 
    858        n.feed('ggo<esc>')
    859        eq(5, exec_lua('return #parser:children().c:trees()'))
    860        eq({
    861          { 0, 0, 8, 0 }, -- root tree
    862          { 2, 26, 2, 63 }, -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y))
    863          { 3, 29, 3, 66 }, -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y))
    864          { 4, 14, 4, 17 }, -- VALUE 123
    865          { 5, 15, 5, 18 }, -- VALUE1 123
    866          { 6, 15, 6, 18 }, -- VALUE2 123
    867        }, get_ranges())
    868      end)
    869    end)
    870 
    871    describe('when using the offset directive', function()
    872      it('shifts the range by the directive amount', function()
    873        exec_lua(function()
    874          _G.parser = vim.treesitter.get_parser(0, 'c', {
    875            injections = {
    876              c = (
    877                '(preproc_def ((preproc_arg) @injection.content (#set! injection.language "c") (#offset! @injection.content 0 2 0 -1))) '
    878                .. '(preproc_function_def value: (preproc_arg) @injection.content (#set! injection.language "c"))'
    879              ),
    880            },
    881          })
    882          _G.parser:parse(true)
    883        end)
    884 
    885        eq('table', exec_lua('return type(parser:children().c)'))
    886        eq({
    887          { 0, 0, 7, 0 }, -- root tree
    888          { 1, 26, 1, 63 }, -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y))
    889          { 2, 29, 2, 66 }, -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y))
    890          { 3, 16, 3, 16 }, -- VALUE 123
    891          { 4, 17, 4, 17 }, -- VALUE1 123
    892          { 5, 17, 5, 17 }, -- VALUE2 123
    893        }, get_ranges())
    894      end)
    895      it('applies offsets to quantified captures', function()
    896        local function get_ltree_ranges()
    897          return exec_lua(function()
    898            local result = {}
    899            _G.parser:for_each_tree(function(_, ltree)
    900              table.insert(result, ltree:included_regions())
    901            end)
    902            return result
    903          end)
    904        end
    905 
    906        exec_lua(function()
    907          _G.parser = vim.treesitter.get_parser(0, 'c', {
    908            injections = {
    909              c = '((preproc_def (preproc_arg) @injection.content)+ (#set! injection.language "c") (#offset! @injection.content 0 1 0 -1))',
    910            },
    911          })
    912          _G.parser:parse(true)
    913        end)
    914 
    915        eq('table', exec_lua('return type(parser:children().c)'))
    916        eq({
    917          { {} }, -- root tree
    918          {
    919            {
    920              { 3, 15, 163, 3, 16, 164 }, -- VALUE 123
    921              { 4, 16, 182, 4, 17, 183 }, -- VALUE1 123
    922              { 5, 16, 201, 5, 17, 202 }, -- VALUE2 123
    923            },
    924          },
    925        }, get_ltree_ranges())
    926      end)
    927      it('lists all directives', function()
    928        local res_list = exec_lua(function()
    929          local query = vim.treesitter.query
    930 
    931          local list = query.list_directives()
    932 
    933          table.sort(list)
    934 
    935          return list
    936        end)
    937 
    938        eq({ 'gsub!', 'offset!', 'set!', 'trim!' }, res_list)
    939      end)
    940    end)
    941  end)
    942 
    943  it('clips nested injections #34098', function()
    944    insert([=[
    945      ```lua
    946      vim.cmd([[
    947      set noswapfile
    948      set noswapfile
    949      set noswapfile
    950      ]])
    951      ```
    952    ]=])
    953 
    954    local result = exec_lua(function()
    955      local parser = vim.treesitter.get_parser(0, 'markdown')
    956      parser:parse(true)
    957 
    958      return parser._children.lua._children.vim:included_regions()
    959    end)
    960 
    961    local expected = {
    962      {
    963        { 1, 10, 17, 2, 0, 18 },
    964        { 2, 0, 18, 3, 0, 33 },
    965        { 3, 0, 33, 4, 0, 48 },
    966        { 4, 0, 48, 5, 0, 63 },
    967      },
    968    }
    969    eq(expected, result)
    970  end)
    971 
    972  describe('when getting the language for a range', function()
    973    before_each(function()
    974      insert([[
    975 int x = INT_MAX;
    976 #define VALUE 123456789
    977      ]])
    978    end)
    979 
    980    it('returns the correct language tree', function()
    981      local result = exec_lua(function()
    982        local parser = vim.treesitter.get_parser(0, 'c', {
    983          injections = {
    984            c = '(preproc_def (preproc_arg) @injection.content (#set! injection.language "c"))',
    985          },
    986        })
    987        parser:parse(true)
    988 
    989        local sub_tree = parser:language_for_range({ 1, 18, 1, 19 })
    990 
    991        return sub_tree == parser:children().c
    992      end)
    993 
    994      eq(true, result)
    995    end)
    996  end)
    997 
    998  describe('when setting the node for an injection', function()
    999    before_each(function()
   1000      insert([[
   1001 print()
   1002      ]])
   1003    end)
   1004 
   1005    it('ignores optional captures #23100', function()
   1006      local result = exec_lua(function()
   1007        local parser = vim.treesitter.get_parser(0, 'lua', {
   1008          injections = {
   1009            lua = (
   1010              '(function_call '
   1011              .. '(arguments '
   1012              .. '(string)? @injection.content '
   1013              .. '(number)? @injection.content '
   1014              .. '(#offset! @injection.content 0 1 0 -1) '
   1015              .. '(#set! injection.language "c")))'
   1016            ),
   1017          },
   1018        })
   1019        parser:parse(true)
   1020 
   1021        return parser:is_valid()
   1022      end)
   1023 
   1024      eq(true, result)
   1025    end)
   1026  end)
   1027 
   1028  describe('when getting/setting match data', function()
   1029    describe('when setting for the whole match', function()
   1030      it('sets/gets the data correctly', function()
   1031        insert([[
   1032          int x = 3;
   1033        ]])
   1034 
   1035        local result = exec_lua(function()
   1036          local query =
   1037            vim.treesitter.query.parse('c', '((number_literal) @number (#set! "key" "value"))')
   1038          local parser = vim.treesitter.get_parser(0, 'c')
   1039 
   1040          local _, _, metadata = query:iter_matches(parser:parse()[1]:root(), 0, 0, -1)()
   1041          return metadata.key
   1042        end)
   1043 
   1044        eq('value', result)
   1045      end)
   1046 
   1047      describe('when setting a key on a capture', function()
   1048        it('creates the nested table', function()
   1049          insert([[
   1050            int x = 3;
   1051          ]])
   1052 
   1053          local result = exec_lua(function()
   1054            local query = vim.treesitter.query.parse(
   1055              'c',
   1056              '((number_literal) @number (#set! @number "key" "value"))'
   1057            )
   1058            local parser = vim.treesitter.get_parser(0, 'c')
   1059 
   1060            local _, _, metadata = query:iter_matches(parser:parse()[1]:root(), 0, 0, -1)()
   1061            local _, nested_tbl = next(metadata)
   1062            return nested_tbl.key
   1063          end)
   1064 
   1065          eq('value', result)
   1066        end)
   1067 
   1068        it('does not overwrite the nested table', function()
   1069          insert([[
   1070            int x = 3;
   1071          ]])
   1072 
   1073          local result = exec_lua(function()
   1074            local query = vim.treesitter.query.parse(
   1075              'c',
   1076              '((number_literal) @number (#set! @number "key" "value") (#set! @number "key2" "value2"))'
   1077            )
   1078            local parser = vim.treesitter.get_parser(0, 'c')
   1079 
   1080            local _, _, metadata = query:iter_matches(parser:parse()[1]:root(), 0, 0, -1)()
   1081            local _, nested_tbl = next(metadata)
   1082            return nested_tbl
   1083          end)
   1084          local expected = {
   1085            ['key'] = 'value',
   1086            ['key2'] = 'value2',
   1087          }
   1088 
   1089          eq(expected, result)
   1090        end)
   1091      end)
   1092    end)
   1093  end)
   1094 
   1095  describe('trim! directive', function()
   1096    it('can trim all whitespace', function()
   1097      exec_lua(function()
   1098        local lines = {
   1099          '        print([[',
   1100          '',
   1101          '            f',
   1102          '     helllo',
   1103          '  there',
   1104          '  asdf',
   1105          '  asdfassd   ',
   1106          '',
   1107          '',
   1108          '',
   1109          '  ]])',
   1110          '  print([[',
   1111          '        ',
   1112          '        ',
   1113          '        ',
   1114          '  ]])',
   1115          '',
   1116          '  print([[]])',
   1117          '',
   1118          '  print([[',
   1119          '  ]])',
   1120          '',
   1121          '  print([[     hello 😃    ]])',
   1122        }
   1123        vim.api.nvim_buf_set_lines(0, 0, -1, true, lines)
   1124      end)
   1125      exec_lua(function()
   1126        vim.treesitter.start(0, 'lua')
   1127      end)
   1128 
   1129      local query_text = [[
   1130       ; query
   1131        ((string_content) @str)
   1132      ]]
   1133      eq({
   1134        { 'str', { 0, 16, 10, 2 } },
   1135        { 'str', { 11, 10, 15, 2 } },
   1136        { 'str', { 17, 10, 17, 10 } },
   1137        { 'str', { 19, 10, 20, 2 } },
   1138        { 'str', { 22, 10, 22, 29 } },
   1139      }, run_query('lua', query_text))
   1140 
   1141      local trim_query_text = [[
   1142        ; query
   1143        ((string_content) @str
   1144          (#trim! @str 1 1 1 1))
   1145      ]]
   1146 
   1147      eq({
   1148        { 'str', { 2, 12, 6, 10 } },
   1149        { 'str', { 11, 10, 11, 10 } },
   1150        { 'str', { 17, 10, 17, 10 } },
   1151        { 'str', { 19, 10, 19, 10 } },
   1152        { 'str', { 22, 15, 22, 25 } },
   1153      }, run_query('lua', trim_query_text))
   1154    end)
   1155 
   1156    it('trims only empty lines by default (backwards compatible)', function()
   1157      insert(dedent [[
   1158      ## Heading
   1159 
   1160      With some text
   1161 
   1162      ## And another
   1163 
   1164      With some more here]])
   1165 
   1166      local query_text = [[
   1167        ; query
   1168        ((section) @fold
   1169          (#trim! @fold))
   1170      ]]
   1171 
   1172      exec_lua(function()
   1173        vim.treesitter.start(0, 'markdown')
   1174      end)
   1175 
   1176      eq({
   1177        { 'fold', { 0, 0, 2, 14 } },
   1178        { 'fold', { 4, 0, 6, 19 } },
   1179      }, run_query('markdown', query_text))
   1180    end)
   1181 
   1182    it('can trim lines', function()
   1183      insert(dedent [[
   1184      - Fold list
   1185        - Fold list
   1186          - Fold list
   1187          - Fold list
   1188        - Fold list
   1189      - Fold list
   1190      ]])
   1191 
   1192      local query_text = [[
   1193        ; query
   1194        ((list_item
   1195          (list)) @fold
   1196          (#trim! @fold 1 1 1 1))
   1197      ]]
   1198 
   1199      exec_lua(function()
   1200        vim.treesitter.start(0, 'markdown')
   1201      end)
   1202 
   1203      eq({
   1204        { 'fold', { 0, 0, 4, 13 } },
   1205        { 'fold', { 1, 2, 3, 15 } },
   1206      }, run_query('markdown', query_text))
   1207    end)
   1208  end)
   1209 
   1210  it('tracks the root range properly (#22911)', function()
   1211    insert([[
   1212      int main() {
   1213        int x = 3;
   1214      }]])
   1215 
   1216    local query0 = [[
   1217      (declaration) @declaration
   1218      (function_definition) @function
   1219    ]]
   1220 
   1221    exec_lua(function()
   1222      vim.treesitter.start(0, 'c')
   1223    end)
   1224 
   1225    eq({
   1226      { 'function', { 0, 0, 2, 1 } },
   1227      { 'declaration', { 1, 2, 1, 12 } },
   1228    }, run_query('c', query0))
   1229 
   1230    n.command 'normal ggO'
   1231    insert('int a;')
   1232 
   1233    eq({
   1234      { 'declaration', { 0, 0, 0, 6 } },
   1235      { 'function', { 1, 0, 3, 1 } },
   1236      { 'declaration', { 2, 2, 2, 12 } },
   1237    }, run_query('c', query0))
   1238  end)
   1239 
   1240  it('handles ranges when source is a multiline string (#20419)', function()
   1241    local source = [==[
   1242      vim.cmd[[
   1243        set number
   1244        set cmdheight=2
   1245        set lastsatus=2
   1246      ]]
   1247 
   1248      set query = [[;; query
   1249        ((function_call
   1250          name: [
   1251            (identifier) @_cdef_identifier
   1252            (_ _ (identifier) @_cdef_identifier)
   1253          ]
   1254          arguments: (arguments (string content: _ @injection.content)))
   1255          (#set! injection.language "c")
   1256          (#eq? @_cdef_identifier "cdef"))
   1257      ]]
   1258    ]==]
   1259 
   1260    local r = exec_lua(function()
   1261      local parser = vim.treesitter.get_string_parser(source, 'lua')
   1262      parser:parse(true)
   1263      local ranges = {}
   1264      parser:for_each_tree(function(tstree, tree)
   1265        ranges[tree:lang()] = { tstree:root():range(true) }
   1266      end)
   1267      return ranges
   1268    end)
   1269 
   1270    eq({
   1271      lua = { 0, 6, 6, 16, 4, 438 },
   1272      query = { 6, 20, 113, 15, 6, 431 },
   1273      vim = { 1, 0, 16, 4, 6, 89 },
   1274    }, r)
   1275 
   1276    -- The above ranges are provided directly from treesitter, however query directives may mutate
   1277    -- the ranges but only provide a Range4. Strip the byte entries from the ranges and make sure
   1278    -- add_bytes() produces the same result.
   1279 
   1280    local rb = exec_lua(function()
   1281      local add_bytes = require('vim.treesitter._range').add_bytes
   1282      for lang, range in pairs(r) do
   1283        r[lang] = { range[1], range[2], range[4], range[5] }
   1284        r[lang] = add_bytes(source, r[lang])
   1285      end
   1286      return r
   1287    end)
   1288 
   1289    eq(rb, r)
   1290  end)
   1291 
   1292  it('does not produce empty injection ranges (#23409)', function()
   1293    insert [[
   1294      Examples: >lua
   1295        local a = {}
   1296 <
   1297    ]]
   1298 
   1299    -- This is not a valid injection since (code) has children and include-children is not set
   1300    exec_lua(function()
   1301      _G.parser1 = require('vim.treesitter.languagetree').new(0, 'vimdoc', {
   1302        injections = {
   1303          vimdoc = '((codeblock (language) @injection.language (code) @injection.content))',
   1304        },
   1305      })
   1306      _G.parser1:parse(true)
   1307    end)
   1308 
   1309    eq(0, exec_lua('return #vim.tbl_keys(parser1:children())'))
   1310 
   1311    exec_lua(function()
   1312      _G.parser2 = require('vim.treesitter.languagetree').new(0, 'vimdoc', {
   1313        injections = {
   1314          vimdoc = '((codeblock (language) @injection.language (code) @injection.content) (#set! injection.include-children))',
   1315        },
   1316      })
   1317      _G.parser2:parse(true)
   1318    end)
   1319 
   1320    eq(1, exec_lua('return #vim.tbl_keys(parser2:children())'))
   1321    eq({ { { 1, 0, 21, 2, 0, 42 } } }, exec_lua('return parser2:children().lua:included_regions()'))
   1322  end)
   1323 
   1324  it('parses injections incrementally', function()
   1325    insert(dedent [[
   1326      >lua
   1327        local a = {}
   1328      <
   1329 
   1330      >lua
   1331        local b = {}
   1332      <
   1333 
   1334      >lua
   1335        local c = {}
   1336      <
   1337 
   1338      >lua
   1339        local d = {}
   1340      <
   1341 
   1342      >lua
   1343        local e = {}
   1344      <
   1345 
   1346      >lua
   1347        local f = {}
   1348      <
   1349 
   1350      >lua
   1351        local g = {}
   1352      <
   1353    ]])
   1354 
   1355    exec_lua(function()
   1356      _G.parser = require('vim.treesitter.languagetree').new(0, 'vimdoc', {
   1357        injections = {
   1358          vimdoc = '((codeblock (language) @injection.language (code) @injection.content) (#set! injection.include-children))',
   1359        },
   1360      })
   1361    end)
   1362 
   1363    --- Do not parse injections by default
   1364    eq(
   1365      0,
   1366      exec_lua(function()
   1367        _G.parser:parse()
   1368        return #vim.tbl_keys(_G.parser:children())
   1369      end)
   1370    )
   1371 
   1372    --- Only parse injections between lines 0, 2
   1373    eq(
   1374      1,
   1375      exec_lua(function()
   1376        _G.parser:parse({ 0, 2 })
   1377        return #_G.parser:children().lua:trees()
   1378      end)
   1379    )
   1380 
   1381    eq(
   1382      1,
   1383      exec_lua(function()
   1384        _G.parser:parse({ 2, 6 })
   1385        return #_G.parser:children().lua:trees()
   1386      end)
   1387    )
   1388 
   1389    eq(
   1390      7,
   1391      exec_lua(function()
   1392        _G.parser:parse(true)
   1393        return #_G.parser:children().lua:trees()
   1394      end)
   1395    )
   1396  end)
   1397 
   1398  describe('languagetree is_valid()', function()
   1399    before_each(function()
   1400      insert(dedent [[
   1401        Treesitter integration                                 *treesitter*
   1402 
   1403        Nvim integrates the `tree-sitter` library for incremental parsing of buffers:
   1404        https://tree-sitter.github.io/tree-sitter/
   1405 
   1406      ]])
   1407 
   1408      feed(':set ft=help<cr>')
   1409 
   1410      exec_lua(function()
   1411        vim.treesitter
   1412          .get_parser(0, 'vimdoc', {
   1413            injections = {
   1414              vimdoc = '((codeblock (language) @injection.language (code) @injection.content) (#set! injection.include-children))',
   1415            },
   1416          })
   1417          :parse()
   1418      end)
   1419    end)
   1420 
   1421    it('is valid excluding, invalid including children initially', function()
   1422      eq(true, exec_lua('return vim.treesitter.get_parser():is_valid(true)'))
   1423      eq(false, exec_lua('return vim.treesitter.get_parser():is_valid()'))
   1424    end)
   1425 
   1426    it('is fully valid after a full parse', function()
   1427      exec_lua('vim.treesitter.get_parser():parse(true)')
   1428      eq(true, exec_lua('return vim.treesitter.get_parser():is_valid(true)'))
   1429      eq(true, exec_lua('return vim.treesitter.get_parser():is_valid()'))
   1430    end)
   1431 
   1432    it('is valid within a range on parsed tree after parsing it', function()
   1433      exec_lua('vim.treesitter.get_parser():parse({5, 7})')
   1434      eq(true, exec_lua('return vim.treesitter.get_parser():is_valid(true)'))
   1435      eq(true, exec_lua('return vim.treesitter.get_parser():is_valid(nil, {5, 7})'))
   1436    end)
   1437 
   1438    describe('when adding content with injections', function()
   1439      before_each(function()
   1440        feed('G')
   1441        insert(dedent [[
   1442          >lua
   1443            local a = {}
   1444          <
   1445 
   1446        ]])
   1447      end)
   1448 
   1449      it('is fully invalid after changes', function()
   1450        eq(false, exec_lua('return vim.treesitter.get_parser():is_valid(true)'))
   1451        eq(false, exec_lua('return vim.treesitter.get_parser():is_valid()'))
   1452      end)
   1453 
   1454      it('is valid excluding, invalid including children after a rangeless parse', function()
   1455        exec_lua('vim.treesitter.get_parser():parse()')
   1456        eq(true, exec_lua('return vim.treesitter.get_parser():is_valid(true)'))
   1457        eq(false, exec_lua('return vim.treesitter.get_parser():is_valid()'))
   1458      end)
   1459 
   1460      it('is valid within a range on parsed tree after parsing it', function()
   1461        exec_lua('vim.treesitter.get_parser():parse({5, 7})')
   1462        eq(true, exec_lua('return vim.treesitter.get_parser():is_valid(true)'))
   1463        eq(true, exec_lua('return vim.treesitter.get_parser():is_valid(nil, {5, 7})'))
   1464      end)
   1465 
   1466      it(
   1467        'is valid excluding, invalid including children after a range parse that does not lead to parsing non-parsed injections',
   1468        function()
   1469          exec_lua('vim.treesitter.get_parser():parse({2, 4})')
   1470          eq(true, exec_lua('return vim.treesitter.get_parser():is_valid(true)'))
   1471          eq(false, exec_lua('return vim.treesitter.get_parser():is_valid()'))
   1472        end
   1473      )
   1474    end)
   1475 
   1476    describe('when removing content with injections', function()
   1477      before_each(function()
   1478        feed('G')
   1479        insert(dedent [[
   1480          >lua
   1481            local a = {}
   1482          <
   1483 
   1484          >lua
   1485            local a = {}
   1486          <
   1487 
   1488        ]])
   1489 
   1490        exec_lua('vim.treesitter.get_parser():parse(true)')
   1491 
   1492        feed('Gd3k')
   1493      end)
   1494 
   1495      it('is fully invalid after changes', function()
   1496        eq(false, exec_lua('return vim.treesitter.get_parser():is_valid(true)'))
   1497        eq(false, exec_lua('return vim.treesitter.get_parser():is_valid()'))
   1498      end)
   1499 
   1500      it('is valid excluding, invalid including children after a rangeless parse', function()
   1501        exec_lua('vim.treesitter.get_parser():parse()')
   1502        eq(true, exec_lua('return vim.treesitter.get_parser():is_valid(true)'))
   1503        eq(false, exec_lua('return vim.treesitter.get_parser():is_valid()'))
   1504      end)
   1505 
   1506      it('is valid within a range parse that leads to parsing modified child tree', function()
   1507        exec_lua('vim.treesitter.get_parser():parse({5, 7})')
   1508        eq(true, exec_lua('return vim.treesitter.get_parser():is_valid(true)'))
   1509        eq(true, exec_lua('return vim.treesitter.get_parser():is_valid(nil, {5, 7})'))
   1510      end)
   1511 
   1512      it(
   1513        'is valid excluding, invalid including children after a range parse that does not lead to parsing modified child tree',
   1514        function()
   1515          exec_lua('vim.treesitter.get_parser():parse({2, 4})')
   1516          eq(true, exec_lua('return vim.treesitter.get_parser():is_valid(true)'))
   1517          eq(false, exec_lua('return vim.treesitter.get_parser():is_valid()'))
   1518        end
   1519      )
   1520    end)
   1521  end)
   1522 end)