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)