fold_spec.lua (26191B)
1 local t = require('test.testutil') 2 local n = require('test.functional.testnvim')() 3 local Screen = require('test.functional.ui.screen') 4 5 local clear = n.clear 6 local eq = t.eq 7 local insert = n.insert 8 local write_file = t.write_file 9 local exec_lua = n.exec_lua 10 local command = n.command 11 local feed = n.feed 12 local poke_eventloop = n.poke_eventloop 13 14 before_each(clear) 15 16 describe('treesitter foldexpr', function() 17 before_each(function() 18 -- open folds to avoid deleting entire folded region 19 exec_lua([[vim.opt.foldlevel = 9]]) 20 end) 21 22 local test_text = [[ 23 void ui_refresh(void) 24 { 25 int width = INT_MAX, height = INT_MAX; 26 bool ext_widgets[kUIExtCount]; 27 for (UIExtension i = 0; (int)i < kUIExtCount; i++) { 28 ext_widgets[i] = true; 29 } 30 31 bool inclusive = ui_override(); 32 for (size_t i = 0; i < ui_count; i++) { 33 UI *ui = uis[i]; 34 width = MIN(ui->width, width); 35 height = MIN(ui->height, height); 36 foo = BAR(ui->bazaar, bazaar); 37 for (UIExtension j = 0; (int)j < kUIExtCount; j++) { 38 ext_widgets[j] &= (ui->ui_ext[j] || inclusive); 39 } 40 } 41 }]] 42 43 local function parse(lang) 44 exec_lua( 45 ([[vim.treesitter.get_parser(0, %s):parse()]]):format(lang and '"' .. lang .. '"' or 'nil') 46 ) 47 end 48 49 local function get_fold_levels() 50 return exec_lua(function() 51 local res = {} 52 for i = 1, vim.api.nvim_buf_line_count(0) do 53 res[i] = vim.treesitter.foldexpr(i) 54 end 55 return res 56 end) 57 end 58 59 it('can compute fold levels', function() 60 insert(test_text) 61 62 parse('c') 63 64 eq({ 65 [1] = '>1', 66 [2] = '1', 67 [3] = '1', 68 [4] = '1', 69 [5] = '>2', 70 [6] = '2', 71 [7] = '2', 72 [8] = '1', 73 [9] = '1', 74 [10] = '>2', 75 [11] = '2', 76 [12] = '2', 77 [13] = '2', 78 [14] = '2', 79 [15] = '>3', 80 [16] = '3', 81 [17] = '3', 82 [18] = '2', 83 [19] = '1', 84 }, get_fold_levels()) 85 end) 86 87 it('recomputes fold levels after lines are added/removed', function() 88 insert(test_text) 89 90 parse('c') 91 92 command('1,2d') 93 poke_eventloop() 94 95 eq({ 96 [1] = '0', 97 [2] = '0', 98 [3] = '>1', 99 [4] = '1', 100 [5] = '1', 101 [6] = '0', 102 [7] = '0', 103 [8] = '>1', 104 [9] = '1', 105 [10] = '1', 106 [11] = '1', 107 [12] = '1', 108 [13] = '>2', 109 [14] = '2', 110 [15] = '2', 111 [16] = '1', 112 [17] = '0', 113 }, get_fold_levels()) 114 115 command('1put!') 116 poke_eventloop() 117 118 eq({ 119 [1] = '>1', 120 [2] = '1', 121 [3] = '1', 122 [4] = '1', 123 [5] = '>2', 124 [6] = '2', 125 [7] = '2', 126 [8] = '1', 127 [9] = '1', 128 [10] = '>2', 129 [11] = '2', 130 [12] = '2', 131 [13] = '2', 132 [14] = '2', 133 [15] = '>3', 134 [16] = '3', 135 [17] = '3', 136 [18] = '2', 137 [19] = '1', 138 }, get_fold_levels()) 139 end) 140 141 it('handles changes close to start/end of folds', function() 142 insert([[ 143 # h1 144 t1 145 # h2 146 t2]]) 147 148 exec_lua([[vim.treesitter.query.set('markdown', 'folds', '(section) @fold')]]) 149 parse('markdown') 150 151 eq({ 152 [1] = '>1', 153 [2] = '1', 154 [3] = '>1', 155 [4] = '1', 156 }, get_fold_levels()) 157 158 feed('2ggo<Esc>') 159 poke_eventloop() 160 161 eq({ 162 [1] = '>1', 163 [2] = '1', 164 [3] = '1', 165 [4] = '>1', 166 [5] = '1', 167 }, get_fold_levels()) 168 169 feed('dd') 170 poke_eventloop() 171 172 eq({ 173 [1] = '>1', 174 [2] = '1', 175 [3] = '>1', 176 [4] = '1', 177 }, get_fold_levels()) 178 179 feed('2ggdd') 180 poke_eventloop() 181 182 eq({ 183 [1] = '0', 184 [2] = '>1', 185 [3] = '1', 186 }, get_fold_levels()) 187 188 feed('u') 189 poke_eventloop() 190 191 eq({ 192 [1] = '>1', 193 [2] = '1', 194 [3] = '>1', 195 [4] = '1', 196 }, get_fold_levels()) 197 198 feed('3ggdd') 199 poke_eventloop() 200 201 eq({ 202 [1] = '>1', 203 [2] = '1', 204 [3] = '1', 205 }, get_fold_levels()) 206 207 feed('u') 208 poke_eventloop() 209 210 eq({ 211 [1] = '>1', 212 [2] = '1', 213 [3] = '>1', 214 [4] = '1', 215 }, get_fold_levels()) 216 217 feed('3ggI#<Esc>') 218 parse() 219 poke_eventloop() 220 221 eq({ 222 [1] = '>1', 223 [2] = '1', 224 [3] = '>2', 225 [4] = '2', 226 }, get_fold_levels()) 227 228 feed('x') 229 parse() 230 poke_eventloop() 231 232 eq({ 233 [1] = '>1', 234 [2] = '1', 235 [3] = '>1', 236 [4] = '1', 237 }, get_fold_levels()) 238 end) 239 240 it('handles changes that trigger multiple on_bytes', function() 241 insert([[ 242 function f() 243 asdf() 244 asdf() 245 end 246 -- comment]]) 247 248 exec_lua(function() 249 vim.treesitter.query.set( 250 'lua', 251 'folds', 252 '[(function_declaration) (parameters) (arguments)] @fold' 253 ) 254 end) 255 parse('lua') 256 257 eq({ 258 [1] = '>1', 259 [2] = '1', 260 [3] = '1', 261 [4] = '1', 262 [5] = '0', 263 }, get_fold_levels()) 264 265 command('1,4join') 266 poke_eventloop() 267 268 eq({ 269 [1] = '0', 270 [2] = '0', 271 }, get_fold_levels()) 272 273 feed('u') 274 poke_eventloop() 275 276 eq({ 277 [1] = '>1', 278 [2] = '1', 279 [3] = '1', 280 [4] = '1', 281 [5] = '0', 282 }, get_fold_levels()) 283 end) 284 285 it('handles multiple folds that overlap at the end and start', function() 286 insert([[ 287 function f() 288 g( 289 function() 290 asdf() 291 end, function() 292 end 293 ) 294 end]]) 295 296 exec_lua(function() 297 vim.treesitter.query.set( 298 'lua', 299 'folds', 300 '[(function_declaration) (function_definition) (parameters) (arguments)] @fold' 301 ) 302 end) 303 parse('lua') 304 305 -- If fold1.stop = fold2.start, then move fold1's stop up so that fold2.start gets proper level. 306 eq({ 307 [1] = '>1', 308 [2] = '>2', 309 [3] = '>3', 310 [4] = '3', 311 [5] = '>3', 312 [6] = '3', 313 [7] = '2', 314 [8] = '1', 315 }, get_fold_levels()) 316 317 command('1,8join') 318 feed('u') 319 poke_eventloop() 320 321 eq({ 322 [1] = '>1', 323 [2] = '>2', 324 [3] = '>3', 325 [4] = '3', 326 [5] = '>3', 327 [6] = '3', 328 [7] = '2', 329 [8] = '1', 330 }, get_fold_levels()) 331 end) 332 333 it('handles multiple folds that start at the same line', function() 334 insert([[ 335 function f(a) 336 if #(g({ 337 k = v, 338 })) > 0 then 339 return 340 end 341 end]]) 342 343 exec_lua(function() 344 vim.treesitter.query.set( 345 'lua', 346 'folds', 347 '[(if_statement) (function_declaration) (parameters) (arguments) (table_constructor)] @fold' 348 ) 349 end) 350 parse('lua') 351 352 eq({ 353 [1] = '>1', 354 [2] = '>3', 355 [3] = '3', 356 [4] = '3', 357 [5] = '2', 358 [6] = '2', 359 [7] = '1', 360 }, get_fold_levels()) 361 362 command('2,6join') 363 poke_eventloop() 364 365 eq({ 366 [1] = '>1', 367 [2] = '1', 368 [3] = '1', 369 }, get_fold_levels()) 370 371 feed('u') 372 poke_eventloop() 373 374 eq({ 375 [1] = '>1', 376 [2] = '>3', 377 [3] = '3', 378 [4] = '3', 379 [5] = '2', 380 [6] = '2', 381 [7] = '1', 382 }, get_fold_levels()) 383 end) 384 385 it('takes account of relevant options', function() 386 insert([[ 387 # h1 388 t1 389 ## h2 390 t2 391 ### h3 392 t3]]) 393 394 exec_lua([[vim.treesitter.query.set('markdown', 'folds', '(section) @fold')]]) 395 parse('markdown') 396 397 command([[set foldminlines=2]]) 398 399 eq({ 400 [1] = '>1', 401 [2] = '1', 402 [3] = '>2', 403 [4] = '2', 404 [5] = '2', 405 [6] = '2', 406 }, get_fold_levels()) 407 408 command([[set foldminlines=1 foldnestmax=1]]) 409 410 eq({ 411 [1] = '>1', 412 [2] = '1', 413 [3] = '1', 414 [4] = '1', 415 [5] = '1', 416 [6] = '1', 417 }, get_fold_levels()) 418 end) 419 420 it('handles quantified patterns', function() 421 insert([[ 422 -- hello 423 -- hello 424 -- hello 425 -- hello 426 -- hello 427 -- hello]]) 428 429 exec_lua([[vim.treesitter.query.set('lua', 'folds', '(comment)+ @fold')]]) 430 parse('lua') 431 432 eq({ 433 [1] = '>1', 434 [2] = '1', 435 [3] = '1', 436 [4] = '1', 437 [5] = '1', 438 [6] = '1', 439 }, get_fold_levels()) 440 end) 441 442 it('updates folds in all windows', function() 443 local screen = Screen.new(60, 48) 444 screen:set_default_attr_ids({ 445 [1] = { background = Screen.colors.Grey, foreground = Screen.colors.DarkBlue }, 446 [2] = { bold = true, foreground = Screen.colors.Blue1 }, 447 [3] = { bold = true, reverse = true }, 448 [4] = { reverse = true }, 449 }) 450 451 parse('c') 452 command([[set foldmethod=expr foldexpr=v:lua.vim.treesitter.foldexpr() foldcolumn=1]]) 453 command('split') 454 455 insert(test_text) 456 457 screen:expect { 458 grid = [[ 459 {1:-}void ui_refresh(void) | 460 {1:│}{ | 461 {1:│} int width = INT_MAX, height = INT_MAX; | 462 {1:│} bool ext_widgets[kUIExtCount]; | 463 {1:-} for (UIExtension i = 0; (int)i < kUIExtCount; i++) { | 464 {1:2} ext_widgets[i] = true; | 465 {1:2} } | 466 {1:│} | 467 {1:│} bool inclusive = ui_override(); | 468 {1:-} for (size_t i = 0; i < ui_count; i++) { | 469 {1:2} UI *ui = uis[i]; | 470 {1:2} width = MIN(ui->width, width); | 471 {1:2} height = MIN(ui->height, height); | 472 {1:2} foo = BAR(ui->bazaar, bazaar); | 473 {1:-} for (UIExtension j = 0; (int)j < kUIExtCount; j++) { | 474 {1:3} ext_widgets[j] &= (ui->ui_ext[j] || inclusive); | 475 {1:3} } | 476 {1:2} } | 477 {1:│}^} | 478 {2:~ }|*4 479 {3:[No Name] [+] }| 480 {1:-}void ui_refresh(void) | 481 {1:│}{ | 482 {1:│} int width = INT_MAX, height = INT_MAX; | 483 {1:│} bool ext_widgets[kUIExtCount]; | 484 {1:-} for (UIExtension i = 0; (int)i < kUIExtCount; i++) { | 485 {1:2} ext_widgets[i] = true; | 486 {1:2} } | 487 {1:│} | 488 {1:│} bool inclusive = ui_override(); | 489 {1:-} for (size_t i = 0; i < ui_count; i++) { | 490 {1:2} UI *ui = uis[i]; | 491 {1:2} width = MIN(ui->width, width); | 492 {1:2} height = MIN(ui->height, height); | 493 {1:2} foo = BAR(ui->bazaar, bazaar); | 494 {1:-} for (UIExtension j = 0; (int)j < kUIExtCount; j++) { | 495 {1:3} ext_widgets[j] &= (ui->ui_ext[j] || inclusive); | 496 {1:3} } | 497 {1:2} } | 498 {1:│}} | 499 {2:~ }|*3 500 {4:[No Name] [+] }| 501 | 502 ]], 503 } 504 505 command('1,2d') 506 507 screen:expect { 508 grid = [[ 509 {1: } ^int width = INT_MAX, height = INT_MAX; | 510 {1: } bool ext_widgets[kUIExtCount]; | 511 {1:-} for (UIExtension i = 0; (int)i < kUIExtCount; i++) { | 512 {1:│} ext_widgets[i] = true; | 513 {1:│} } | 514 {1: } | 515 {1: } bool inclusive = ui_override(); | 516 {1:-} for (size_t i = 0; i < ui_count; i++) { | 517 {1:│} UI *ui = uis[i]; | 518 {1:│} width = MIN(ui->width, width); | 519 {1:│} height = MIN(ui->height, height); | 520 {1:│} foo = BAR(ui->bazaar, bazaar); | 521 {1:-} for (UIExtension j = 0; (int)j < kUIExtCount; j++) { | 522 {1:2} ext_widgets[j] &= (ui->ui_ext[j] || inclusive); | 523 {1:2} } | 524 {1:│} } | 525 {1: }} | 526 {2:~ }|*6 527 {3:[No Name] [+] }| 528 {1: } int width = INT_MAX, height = INT_MAX; | 529 {1: } bool ext_widgets[kUIExtCount]; | 530 {1:-} for (UIExtension i = 0; (int)i < kUIExtCount; i++) { | 531 {1:│} ext_widgets[i] = true; | 532 {1:│} } | 533 {1: } | 534 {1: } bool inclusive = ui_override(); | 535 {1:-} for (size_t i = 0; i < ui_count; i++) { | 536 {1:│} UI *ui = uis[i]; | 537 {1:│} width = MIN(ui->width, width); | 538 {1:│} height = MIN(ui->height, height); | 539 {1:│} foo = BAR(ui->bazaar, bazaar); | 540 {1:-} for (UIExtension j = 0; (int)j < kUIExtCount; j++) { | 541 {1:2} ext_widgets[j] &= (ui->ui_ext[j] || inclusive); | 542 {1:2} } | 543 {1:│} } | 544 {1: }} | 545 {2:~ }|*5 546 {4:[No Name] [+] }| 547 | 548 ]], 549 } 550 551 feed([[O<C-u><C-r>"<BS><Esc>]]) 552 553 screen:expect { 554 grid = [[ 555 {1:-}void ui_refresh(void) | 556 {1:│}^{ | 557 {1:│} int width = INT_MAX, height = INT_MAX; | 558 {1:│} bool ext_widgets[kUIExtCount]; | 559 {1:-} for (UIExtension i = 0; (int)i < kUIExtCount; i++) { | 560 {1:2} ext_widgets[i] = true; | 561 {1:2} } | 562 {1:│} | 563 {1:│} bool inclusive = ui_override(); | 564 {1:-} for (size_t i = 0; i < ui_count; i++) { | 565 {1:2} UI *ui = uis[i]; | 566 {1:2} width = MIN(ui->width, width); | 567 {1:2} height = MIN(ui->height, height); | 568 {1:2} foo = BAR(ui->bazaar, bazaar); | 569 {1:-} for (UIExtension j = 0; (int)j < kUIExtCount; j++) { | 570 {1:3} ext_widgets[j] &= (ui->ui_ext[j] || inclusive); | 571 {1:3} } | 572 {1:2} } | 573 {1:│}} | 574 {2:~ }|*4 575 {3:[No Name] [+] }| 576 {1:-}void ui_refresh(void) | 577 {1:│}{ | 578 {1:│} int width = INT_MAX, height = INT_MAX; | 579 {1:│} bool ext_widgets[kUIExtCount]; | 580 {1:-} for (UIExtension i = 0; (int)i < kUIExtCount; i++) { | 581 {1:2} ext_widgets[i] = true; | 582 {1:2} } | 583 {1:│} | 584 {1:│} bool inclusive = ui_override(); | 585 {1:-} for (size_t i = 0; i < ui_count; i++) { | 586 {1:2} UI *ui = uis[i]; | 587 {1:2} width = MIN(ui->width, width); | 588 {1:2} height = MIN(ui->height, height); | 589 {1:2} foo = BAR(ui->bazaar, bazaar); | 590 {1:-} for (UIExtension j = 0; (int)j < kUIExtCount; j++) { | 591 {1:3} ext_widgets[j] &= (ui->ui_ext[j] || inclusive); | 592 {1:3} } | 593 {1:2} } | 594 {1:│}} | 595 {2:~ }|*3 596 {4:[No Name] [+] }| 597 | 598 ]], 599 } 600 end) 601 602 it("doesn't open folds in diff mode", function() 603 local screen = Screen.new(60, 36) 604 605 parse('c') 606 command( 607 [[set foldmethod=expr foldexpr=v:lua.vim.treesitter.foldexpr() foldcolumn=1 foldlevel=9]] 608 ) 609 insert(test_text) 610 command('16d') 611 612 command('new') 613 insert(test_text) 614 615 command('windo diffthis') 616 feed('do') 617 618 screen:expect([[ 619 {7:+ }{13:+-- 19 lines: void ui_refresh(void)·······················}| 620 {1:~ }|*16 621 {2:[No Name] [+] }| 622 {7:+ }{13:^+-- 19 lines: void ui_refresh(void)·······················}| 623 {1:~ }|*15 624 {3:[No Name] [+] }| 625 | 626 ]]) 627 end) 628 629 it('does not extend closed fold with `o`/`O`', function() 630 local screen = Screen.new(60, 24) 631 632 insert(test_text) 633 parse('c') 634 command([[set foldmethod=expr foldexpr=v:lua.vim.treesitter.foldexpr() foldcolumn=1]]) 635 636 feed('5ggzco') 637 screen:expect({ 638 grid = [[ 639 {7:-}void ui_refresh(void) | 640 {7:│}{ | 641 {7:│} int width = INT_MAX, height = INT_MAX; | 642 {7:│} bool ext_widgets[kUIExtCount]; | 643 {7:+}{13:+--- 3 lines: for (UIExtension i = 0; (int)i < kUIExtCount}| 644 {7:│}^ | 645 {7:│} | 646 {7:│} bool inclusive = ui_override(); | 647 {7:-} for (size_t i = 0; i < ui_count; i++) { | 648 {7:2} UI *ui = uis[i]; | 649 {7:2} width = MIN(ui->width, width); | 650 {7:2} height = MIN(ui->height, height); | 651 {7:2} foo = BAR(ui->bazaar, bazaar); | 652 {7:-} for (UIExtension j = 0; (int)j < kUIExtCount; j++) { | 653 {7:3} ext_widgets[j] &= (ui->ui_ext[j] || inclusive); | 654 {7:3} } | 655 {7:2} } | 656 {7:│}} | 657 {1:~ }|*5 658 {5:-- INSERT --} | 659 ]], 660 }) 661 662 feed('<Esc>O') 663 screen:expect({ 664 grid = [[ 665 {7:-}void ui_refresh(void) | 666 {7:│}{ | 667 {7:│} int width = INT_MAX, height = INT_MAX; | 668 {7:│} bool ext_widgets[kUIExtCount]; | 669 {7:+}{13:+--- 3 lines: for (UIExtension i = 0; (int)i < kUIExtCount}| 670 {7:│}^ | 671 {7:│} |*2 672 {7:│} bool inclusive = ui_override(); | 673 {7:-} for (size_t i = 0; i < ui_count; i++) { | 674 {7:2} UI *ui = uis[i]; | 675 {7:2} width = MIN(ui->width, width); | 676 {7:2} height = MIN(ui->height, height); | 677 {7:2} foo = BAR(ui->bazaar, bazaar); | 678 {7:-} for (UIExtension j = 0; (int)j < kUIExtCount; j++) { | 679 {7:3} ext_widgets[j] &= (ui->ui_ext[j] || inclusive); | 680 {7:3} } | 681 {7:2} } | 682 {7:│}} | 683 {1:~ }|*4 684 {5:-- INSERT --} | 685 ]], 686 }) 687 end) 688 689 it("doesn't open folds that are not touched", function() 690 local screen = Screen.new(40, 8) 691 screen:set_default_attr_ids({ 692 [1] = { foreground = Screen.colors.DarkBlue, background = Screen.colors.Gray }, 693 [2] = { foreground = Screen.colors.DarkBlue, background = Screen.colors.LightGray }, 694 [3] = { foreground = Screen.colors.Blue1, bold = true }, 695 [4] = { bold = true }, 696 }) 697 698 insert([[ 699 # h1 700 t1 701 # h2 702 t2]]) 703 exec_lua([[vim.treesitter.query.set('markdown', 'folds', '(section) @fold')]]) 704 parse('markdown') 705 command( 706 [[set foldmethod=expr foldexpr=v:lua.vim.treesitter.foldexpr() foldcolumn=1 foldlevel=0]] 707 ) 708 709 feed('ggzojo') 710 screen:expect([[ 711 {1:-}# h1 | 712 {1:│}t1 | 713 {1:-}^ | 714 {1:+}{2:+-- 2 lines: # h2·····················}| 715 {3:~ }|*3 716 {4:-- INSERT --} | 717 ]]) 718 719 -- TODO(tomtomjhj): `u` spuriously opens the fold (#26499). 720 feed('<Esc>uzMggzodd') 721 screen:expect([[ 722 {1:-}^t1 | 723 {1:-}# h2 | 724 {1:│}t2 | 725 {3:~ }|*4 726 1 line less; before #2 {MATCH:.*}| 727 ]]) 728 end) 729 730 it("doesn't call get_parser too often when parser is not available", function() 731 -- spy on vim.treesitter.get_parser() to keep track of how many times it is called 732 exec_lua(function() 733 _G.count = 0 734 vim.treesitter.get_parser = (function(wrapped) 735 return function(...) 736 _G.count = _G.count + 1 737 return wrapped(...) 738 end 739 end)(vim.treesitter.get_parser) 740 end) 741 742 insert(test_text) 743 command [[ 744 set filetype=some_filetype_without_treesitter_parser 745 set foldmethod=expr foldexpr=v:lua.vim.treesitter.foldexpr() foldcolumn=1 foldlevel=0 746 ]] 747 748 -- foldexpr will return '0' for all lines 749 local levels = get_fold_levels() ---@type integer[] 750 eq(19, #levels) 751 for lnum, level in ipairs(levels) do 752 eq('0', level, string.format("foldlevel[%d] == %s; expected '0'", lnum, level)) 753 end 754 755 eq( 756 1, 757 exec_lua [[ return _G.count ]], 758 'count should not be as high as the # of lines; actually only once for the buffer.' 759 ) 760 end) 761 762 it('can detect a new parser and refresh folds accordingly', function() 763 local name = t.tmpname() 764 write_file(name, test_text) 765 command('edit ' .. name) 766 command [[ 767 set filetype=some_filetype_without_treesitter_parser 768 set foldmethod=expr foldexpr=v:lua.vim.treesitter.foldexpr() foldcolumn=1 foldlevel=0 769 ]] 770 771 -- foldexpr will return '0' for all lines 772 local function expect_no_folds() 773 local levels = get_fold_levels() ---@type integer[] 774 eq(19, #levels) 775 for lnum, level in ipairs(levels) do 776 eq('0', level, string.format("foldlevel[%d] == %s; expected '0'", lnum, level)) 777 end 778 end 779 expect_no_folds() 780 781 -- reload buffer as c filetype to simulate new parser being found 782 feed('GA// vim: ft=c<Esc>') 783 command([[write | edit]]) 784 local foldlevels = { 785 [1] = '>1', 786 [2] = '1', 787 [3] = '1', 788 [4] = '1', 789 [5] = '>2', 790 [6] = '2', 791 [7] = '2', 792 [8] = '1', 793 [9] = '1', 794 [10] = '>2', 795 [11] = '2', 796 [12] = '2', 797 [13] = '2', 798 [14] = '2', 799 [15] = '>3', 800 [16] = '3', 801 [17] = '3', 802 [18] = '2', 803 [19] = '1', 804 } 805 eq(foldlevels, get_fold_levels()) 806 807 -- only changing filetype should change the parser again 808 command('set ft=some_filetype_without_treesitter_parser') 809 expect_no_folds() 810 811 command('set ft=c') 812 eq(foldlevels, get_fold_levels()) 813 end) 814 815 it('no error when deleting lines at end of buffer with fml=0', function() 816 local screen = Screen.new(40, 2) 817 insert('hello') 818 parse('markdown') 819 command('set foldmethod=expr foldexpr=v:lua.vim.treesitter.foldexpr() foldminlines=0') 820 feed('o<Esc>dd') 821 screen:expect([[ 822 ^hello | 823 | 824 ]]) 825 end) 826 end)