1" Test for folding 2 3source check.vim 4source view_util.vim 5source screendump.vim 6 7func PrepIndent(arg) 8 return [a:arg] + repeat(["\t".a:arg], 5) 9endfu 10 11func Test_address_fold() 12 new 13 call setline(1, ['int FuncName() {/*{{{*/', 1, 2, 3, 4, 5, '}/*}}}*/', 14 \ 'after fold 1', 'after fold 2', 'after fold 3']) 15 setl fen fdm=marker 16 " The next commands should all copy the same part of the buffer, 17 " regardless of the addressing type, since the part to be copied 18 " is folded away 19 :1y 20 call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1)) 21 :.y 22 call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1)) 23 :.+y 24 call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1)) 25 :.,.y 26 call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1)) 27 :sil .1,.y 28 call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1)) 29 " use silent to make E493 go away 30 :sil .+,.y 31 call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1)) 32 :,y 33 call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1)) 34 :,+y 35 call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/','after fold 1'], getreg(0,1,1)) 36 " using .+3 as second address should copy the whole folded line + the next 3 37 " lines 38 :.,+3y 39 call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/', 40 \ 'after fold 1', 'after fold 2', 'after fold 3'], getreg(0,1,1)) 41 :sil .,-2y 42 call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1)) 43 44 " now test again with folding disabled 45 set nofoldenable 46 :1y 47 call assert_equal(['int FuncName() {/*{{{*/'], getreg(0,1,1)) 48 :.y 49 call assert_equal(['int FuncName() {/*{{{*/'], getreg(0,1,1)) 50 :.+y 51 call assert_equal(['1'], getreg(0,1,1)) 52 :.,.y 53 call assert_equal(['int FuncName() {/*{{{*/'], getreg(0,1,1)) 54 " use silent to make E493 go away 55 :sil .1,.y 56 call assert_equal(['int FuncName() {/*{{{*/', '1'], getreg(0,1,1)) 57 " use silent to make E493 go away 58 :sil .+,.y 59 call assert_equal(['int FuncName() {/*{{{*/', '1'], getreg(0,1,1)) 60 :,y 61 call assert_equal(['int FuncName() {/*{{{*/'], getreg(0,1,1)) 62 :,+y 63 call assert_equal(['int FuncName() {/*{{{*/', '1'], getreg(0,1,1)) 64 " using .+3 as second address should copy the whole folded line + the next 3 65 " lines 66 :.,+3y 67 call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3'], getreg(0,1,1)) 68 :7 69 :sil .,-2y 70 call assert_equal(['4', '5', '}/*}}}*/'], getreg(0,1,1)) 71 72 quit! 73endfunc 74 75func Test_indent_fold() 76 new 77 call setline(1, ['', 'a', ' b', ' c']) 78 setl fen fdm=indent 79 2 80 norm! >> 81 let a=map(range(1,4), 'foldclosed(v:val)') 82 call assert_equal([-1,-1,-1,-1], a) 83 bw! 84endfunc 85 86func Test_indent_fold2() 87 new 88 call setline(1, ['', '{{{', '}}}', '{{{', '}}}']) 89 setl fen fdm=marker 90 2 91 norm! >> 92 let a=map(range(1,5), 'v:val->foldclosed()') 93 call assert_equal([-1,-1,-1,4,4], a) 94 bw! 95endfunc 96 97" Test for fold indent with indents greater than 'foldnestmax' 98func Test_indent_fold_max() 99 new 100 setlocal foldmethod=indent 101 setlocal shiftwidth=2 102 " 'foldnestmax' default value is 20 103 call setline(1, "\t\t\t\t\t\ta") 104 call assert_equal(20, foldlevel(1)) 105 setlocal foldnestmax=10 106 call assert_equal(10, foldlevel(1)) 107 setlocal foldnestmax=-1 108 call assert_equal(0, foldlevel(1)) 109 bw! 110endfunc 111 112func Test_manual_fold_with_filter() 113 CheckExecutable cat 114 for type in ['manual', 'marker'] 115 exe 'set foldmethod=' . type 116 new 117 call setline(1, range(1, 20)) 118 4,$fold 119 %foldopen 120 10,$fold 121 %foldopen 122 " This filter command should not have an effect 123 1,8! cat 124 call feedkeys('5ggzdzMGdd', 'xt') 125 call assert_equal(['1', '2', '3', '4', '5', '6', '7', '8', '9'], getline(1, '$')) 126 127 bwipe! 128 set foldmethod& 129 endfor 130endfunc 131 132func Test_indent_fold_with_read() 133 new 134 set foldmethod=indent 135 call setline(1, repeat(["\<Tab>a"], 4)) 136 for n in range(1, 4) 137 call assert_equal(1, foldlevel(n)) 138 endfor 139 140 call writefile(["a", "", "\<Tab>a"], 'Xfile') 141 foldopen 142 2read Xfile 143 %foldclose 144 call assert_equal(1, foldlevel(1)) 145 call assert_equal(2, foldclosedend(1)) 146 call assert_equal(0, foldlevel(3)) 147 call assert_equal(0, foldlevel(4)) 148 call assert_equal(1, foldlevel(5)) 149 call assert_equal(7, 5->foldclosedend()) 150 151 bwipe! 152 set foldmethod& 153 call delete('Xfile') 154endfunc 155 156func Test_combining_folds_indent() 157 new 158 let one = "\<Tab>a" 159 let zero = 'a' 160 call setline(1, [one, one, zero, zero, zero, one, one, one]) 161 set foldmethod=indent 162 3,5d 163 %foldclose 164 call assert_equal(5, foldclosedend(1)) 165 166 set foldmethod& 167 bwipe! 168endfunc 169 170func Test_combining_folds_marker() 171 new 172 call setline(1, ['{{{', '}}}', '', '', '', '{{{', '', '}}}']) 173 set foldmethod=marker 174 3,5d 175 %foldclose 176 call assert_equal(2, foldclosedend(1)) 177 178 set foldmethod& 179 bwipe! 180endfunc 181 182func Test_folds_marker_in_comment() 183 new 184 call setline(1, ['" foo', 'bar', 'baz']) 185 setl fen fdm=marker 186 setl com=sO:\"\ -,mO:\"\ \ ,eO:\"\",:\" cms=\"%s 187 norm! zf2j 188 setl nofen 189 :1y 190 call assert_equal(['" foo{{{'], getreg(0,1,1)) 191 :+2y 192 call assert_equal(['baz"}}}'], getreg(0,1,1)) 193 194 set foldmethod& 195 bwipe! 196endfunc 197 198func s:TestFoldExpr(lnum) 199 let thisline = getline(a:lnum) 200 if thisline == 'a' 201 return 1 202 elseif thisline == 'b' 203 return 0 204 elseif thisline == 'c' 205 return '<1' 206 elseif thisline == 'd' 207 return '>1' 208 endif 209 return 0 210endfunction 211 212func Test_update_folds_expr_read() 213 new 214 call setline(1, ['a', 'a', 'a', 'a', 'a', 'a']) 215 set foldmethod=expr 216 set foldexpr=s:TestFoldExpr(v:lnum) 217 2 218 foldopen 219 call writefile(['b', 'b', 'a', 'a', 'd', 'a', 'a', 'c'], 'Xfile') 220 read Xfile 221 %foldclose 222 call assert_equal(2, foldclosedend(1)) 223 call assert_equal(0, foldlevel(3)) 224 call assert_equal(0, 4->foldlevel()) 225 call assert_equal(6, foldclosedend(5)) 226 call assert_equal(10, foldclosedend(7)) 227 call assert_equal(14, foldclosedend(11)) 228 229 call delete('Xfile') 230 bwipe! 231 set foldmethod& foldexpr& 232endfunc 233 234func Check_foldlevels(expected) 235 call assert_equal(a:expected, map(range(1, line('$')), 'foldlevel(v:val)')) 236endfunc 237 238func Test_move_folds_around_manual() 239 new 240 let input = PrepIndent("a") + PrepIndent("b") + PrepIndent("c") 241 call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c")) 242 let folds=[-1, 2, 2, 2, 2, 2, -1, 8, 8, 8, 8, 8, -1, 14, 14, 14, 14, 14] 243 " all folds closed 244 set foldenable foldlevel=0 fdm=indent 245 " needs a forced redraw 246 redraw! 247 set fdm=manual 248 call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)')) 249 call assert_equal(input, getline(1, '$')) 250 7,12m0 251 call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$')) 252 call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)')) 253 10,12m0 254 call assert_equal(PrepIndent("a")[1:] + PrepIndent("b") + ["a"] + PrepIndent("c"), getline(1, '$')) 255 call assert_equal([1, 1, 1, 1, 1, -1, 7, 7, 7, 7, 7, -1, -1, 14, 14, 14, 14, 14], map(range(1, line('$')), 'foldclosed(v:val)')) 256 " moving should not close the folds 257 %d 258 call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c")) 259 set fdm=indent 260 redraw! 261 set fdm=manual 262 call cursor(2, 1) 263 %foldopen 264 7,12m0 265 let folds=repeat([-1], 18) 266 call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$')) 267 call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)')) 268 norm! zM 269 " folds are not corrupted and all have been closed 270 call assert_equal([-1, 2, 2, 2, 2, 2, -1, 8, 8, 8, 8, 8, -1, 14, 14, 14, 14, 14], map(range(1, line('$')), 'foldclosed(v:val)')) 271 %d 272 call setline(1, ["a", "\tb", "\tc", "\td", "\te"]) 273 set fdm=indent 274 redraw! 275 set fdm=manual 276 %foldopen 277 3m4 278 %foldclose 279 call assert_equal(["a", "\tb", "\td", "\tc", "\te"], getline(1, '$')) 280 call assert_equal([-1, 5, 5, 5, 5], map(range(1, line('$')), 'foldclosedend(v:val)')) 281 %d 282 call setline(1, ["a", "\tb", "\tc", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"]) 283 set fdm=indent foldlevel=0 284 set fdm=manual 285 %foldopen 286 3m1 287 %foldclose 288 call assert_equal(["a", "\tc", "\tb", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"], getline(1, '$')) 289 call assert_equal(0, foldlevel(2)) 290 call assert_equal(5, foldclosedend(3)) 291 call assert_equal([-1, -1, 3, 3, 3, -1, 7, 7, 7, 7], map(range(1, line('$')), 'foldclosed(v:val)')) 292 2,6m$ 293 %foldclose 294 call assert_equal(5, foldclosedend(2)) 295 call assert_equal(0, foldlevel(6)) 296 call assert_equal(9, foldclosedend(7)) 297 call assert_equal([-1, 2, 2, 2, 2, -1, 7, 7, 7, -1], map(range(1, line('$')), 'foldclosed(v:val)')) 298 299 %d 300 " Ensure moving around the edges still works. 301 call setline(1, PrepIndent("a") + repeat(["a"], 3) + ["\ta"]) 302 set fdm=indent foldlevel=0 303 set fdm=manual 304 %foldopen 305 6m$ 306 " The first fold has been truncated to the 5'th line. 307 " Second fold has been moved up because the moved line is now below it. 308 call Check_foldlevels([0, 1, 1, 1, 1, 0, 0, 0, 1, 0]) 309 310 %delete 311 set fdm=indent foldlevel=0 312 call setline(1, [ 313 \ "a", 314 \ "\ta", 315 \ "\t\ta", 316 \ "\t\ta", 317 \ "\t\ta", 318 \ "a", 319 \ "a"]) 320 set fdm=manual 321 %foldopen! 322 4,5m6 323 call Check_foldlevels([0, 1, 2, 0, 0, 0, 0]) 324 325 %delete 326 set fdm=indent 327 call setline(1, [ 328 \ "\ta", 329 \ "\t\ta", 330 \ "\t\ta", 331 \ "\t\ta", 332 \ "\ta", 333 \ "\t\ta", 334 \ "\t\ta", 335 \ "\t\ta", 336 \ "\ta", 337 \ "\t\ta", 338 \ "\t\ta", 339 \ "\t\ta", 340 \ "\t\ta", 341 \ "\ta", 342 \ "a"]) 343 set fdm=manual 344 %foldopen! 345 13m7 346 call Check_foldlevels([1, 2, 2, 2, 1, 2, 2, 1, 1, 1, 2, 2, 2, 1, 0]) 347 348 bw! 349endfunc 350 351func Test_move_folds_around_indent() 352 new 353 let input = PrepIndent("a") + PrepIndent("b") + PrepIndent("c") 354 call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c")) 355 let folds=[-1, 2, 2, 2, 2, 2, -1, 8, 8, 8, 8, 8, -1, 14, 14, 14, 14, 14] 356 " all folds closed 357 set fdm=indent 358 call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)')) 359 call assert_equal(input, getline(1, '$')) 360 7,12m0 361 call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$')) 362 call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)')) 363 10,12m0 364 call assert_equal(PrepIndent("a")[1:] + PrepIndent("b") + ["a"] + PrepIndent("c"), getline(1, '$')) 365 call assert_equal([1, 1, 1, 1, 1, -1, 7, 7, 7, 7, 7, -1, -1, 14, 14, 14, 14, 14], map(range(1, line('$')), 'foldclosed(v:val)')) 366 " moving should not close the folds 367 %d 368 call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c")) 369 set fdm=indent 370 call cursor(2, 1) 371 %foldopen 372 7,12m0 373 let folds=repeat([-1], 18) 374 call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$')) 375 call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)')) 376 norm! zM 377 " folds are not corrupted and all have been closed 378 call assert_equal([-1, 2, 2, 2, 2, 2, -1, 8, 8, 8, 8, 8, -1, 14, 14, 14, 14, 14], map(range(1, line('$')), 'foldclosed(v:val)')) 379 %d 380 call setline(1, ["a", "\tb", "\tc", "\td", "\te"]) 381 set fdm=indent 382 %foldopen 383 3m4 384 %foldclose 385 call assert_equal(["a", "\tb", "\td", "\tc", "\te"], getline(1, '$')) 386 call assert_equal([-1, 5, 5, 5, 5], map(range(1, line('$')), 'foldclosedend(v:val)')) 387 %d 388 call setline(1, ["a", "\tb", "\tc", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"]) 389 set fdm=indent foldlevel=0 390 %foldopen 391 3m1 392 %foldclose 393 call assert_equal(["a", "\tc", "\tb", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"], getline(1, '$')) 394 call assert_equal(1, foldlevel(2)) 395 call assert_equal(5, foldclosedend(3)) 396 call assert_equal([-1, 2, 2, 2, 2, -1, 7, 7, 7, 7], map(range(1, line('$')), 'foldclosed(v:val)')) 397 2,6m$ 398 %foldclose 399 call assert_equal(9, foldclosedend(2)) 400 call assert_equal(1, foldlevel(6)) 401 call assert_equal(9, foldclosedend(7)) 402 call assert_equal([-1, 2, 2, 2, 2, 2, 2, 2, 2, -1], map(range(1, line('$')), 'foldclosed(v:val)')) 403 " Ensure moving around the edges still works. 404 %d 405 call setline(1, PrepIndent("a") + repeat(["a"], 3) + ["\ta"]) 406 set fdm=indent foldlevel=0 407 %foldopen 408 6m$ 409 " The first fold has been truncated to the 5'th line. 410 " Second fold has been moved up because the moved line is now below it. 411 call Check_foldlevels([0, 1, 1, 1, 1, 0, 0, 0, 1, 1]) 412 bw! 413endfunc 414 415func Test_folddoopen_folddoclosed() 416 new 417 call setline(1, range(1, 9)) 418 set foldmethod=manual 419 1,3 fold 420 6,8 fold 421 422 " Test without range. 423 folddoopen s/$/o/ 424 folddoclosed s/$/c/ 425 call assert_equal(['1c', '2c', '3c', 426 \ '4o', '5o', 427 \ '6c', '7c', '8c', 428 \ '9o'], getline(1, '$')) 429 430 " Test with range. 431 call setline(1, range(1, 9)) 432 1,8 folddoopen s/$/o/ 433 4,$ folddoclosed s/$/c/ 434 call assert_equal(['1', '2', '3', 435 \ '4o', '5o', 436 \ '6c', '7c', '8c', 437 \ '9'], getline(1, '$')) 438 439 set foldmethod& 440 bw! 441endfunc 442 443func Test_fold_error() 444 new 445 call setline(1, [1, 2]) 446 447 for fm in ['indent', 'expr', 'syntax', 'diff'] 448 exe 'set foldmethod=' . fm 449 call assert_fails('norm zf', 'E350:') 450 call assert_fails('norm zd', 'E351:') 451 call assert_fails('norm zE', 'E352:') 452 endfor 453 454 set foldmethod=manual 455 call assert_fails('norm zd', 'E490:') 456 call assert_fails('norm zo', 'E490:') 457 call assert_fails('3fold', 'E16:') 458 459 set foldmethod=marker 460 set nomodifiable 461 call assert_fails('1,2fold', 'E21:') 462 463 set modifiable& 464 set foldmethod& 465 bw! 466endfunc 467 468func Test_foldtext_recursive() 469 new 470 call setline(1, ['{{{', 'some text', '}}}']) 471 setlocal foldenable foldmethod=marker foldtext=foldtextresult(v\:foldstart) 472 " This was crashing because of endless recursion. 473 2foldclose 474 redraw 475 call assert_equal(1, foldlevel(2)) 476 call assert_equal(1, foldclosed(2)) 477 call assert_equal(3, foldclosedend(2)) 478 bwipe! 479endfunc 480 481" Various fold related tests 482 483" Basic test if a fold can be created, opened, moving to the end and closed 484func Test_fold_manual() 485 new 486 set fdm=manual 487 488 let content = ['1 aa', '2 bb', '3 cc'] 489 call append(0, content) 490 call cursor(1, 1) 491 normal zf2j 492 call assert_equal('1 aa', getline(foldclosed('.'))) 493 normal zo 494 call assert_equal(-1, foldclosed('.')) 495 normal ]z 496 call assert_equal('3 cc', getline('.')) 497 normal zc 498 call assert_equal('1 aa', getline(foldclosed('.'))) 499 500 set fdm& 501 bw! 502endfunc 503 504" test folding with markers. 505func Test_fold_marker() 506 new 507 set fdm=marker fdl=1 fdc=3 508 509 let content = ['4 dd {{{', '5 ee {{{ }}}', '6 ff }}}'] 510 call append(0, content) 511 call cursor(2, 1) 512 call assert_equal(2, foldlevel('.')) 513 normal [z 514 call assert_equal(1, foldlevel('.')) 515 exe "normal jo{{ \<Esc>r{jj" 516 call assert_equal(1, foldlevel('.')) 517 normal kYpj 518 call assert_equal(0, foldlevel('.')) 519 520 " Use only closing fold marker (without and with a count) 521 set fdl& 522 %d _ 523 call setline(1, ['one }}}', 'two']) 524 call assert_equal([0, 0], [foldlevel(1), foldlevel(2)]) 525 %d _ 526 call setline(1, ['one }}}4', 'two']) 527 call assert_equal([4, 3], [foldlevel(1), foldlevel(2)]) 528 529 set fdm& fdl& fdc& 530 bw! 531endfunc 532 533" test create fold markers with C filetype 534func Test_fold_create_marker_in_C() 535 bw! 536 set fdm=marker fdl=9 537 set filetype=c 538 539 let content =<< trim [CODE] 540 /* 541 * comment 542 * 543 * 544 */ 545 int f(int* p) { 546 *p = 3; 547 return 0; 548 } 549 [CODE] 550 551 for c in range(len(content) - 1) 552 bw! 553 call append(0, content) 554 call cursor(c + 1, 1) 555 norm! zfG 556 call assert_equal(content[c] . (c < 4 ? '{{{' : '/*{{{*/'), getline(c + 1)) 557 endfor 558 559 set fdm& fdl& 560 bw! 561endfunc 562 563" test folding with indent 564func Test_fold_indent() 565 new 566 set fdm=indent sw=2 567 568 let content = ['1 aa', '2 bb', '3 cc'] 569 call append(0, content) 570 call cursor(2, 1) 571 exe "normal i \<Esc>jI " 572 call assert_equal(2, foldlevel('.')) 573 normal k 574 call assert_equal(1, foldlevel('.')) 575 576 set fdm& sw& 577 bw! 578endfunc 579 580" test syntax folding 581func Test_fold_syntax() 582 CheckFeature syntax 583 584 new 585 set fdm=syntax fdl=0 586 587 syn region Hup start="dd" end="ii" fold contains=Fd1,Fd2,Fd3 588 syn region Fd1 start="ee" end="ff" fold contained 589 syn region Fd2 start="gg" end="hh" fold contained 590 syn region Fd3 start="commentstart" end="commentend" fold contained 591 let content = ['3 cc', '4 dd {{{', '5 ee {{{ }}}', '{{{{', '6 ff }}}', 592 \ '6 ff }}}', '7 gg', '8 hh', '9 ii'] 593 call append(0, content) 594 normal Gzk 595 call assert_equal('9 ii', getline('.')) 596 normal k 597 call assert_equal('3 cc', getline('.')) 598 exe "normal jAcommentstart \<Esc>Acommentend" 599 set fdl=1 600 normal 3j 601 call assert_equal('7 gg', getline('.')) 602 set fdl=0 603 exe "normal zO\<C-L>j" 604 call assert_equal('8 hh', getline('.')) 605 syn clear Fd1 Fd2 Fd3 Hup 606 607 set fdm& fdl& 608 bw! 609endfunc 610 611func Flvl() 612 let l = getline(v:lnum) 613 if l =~ "bb$" 614 return 2 615 elseif l =~ "gg$" 616 return "s1" 617 elseif l =~ "ii$" 618 return ">2" 619 elseif l =~ "kk$" 620 return "0" 621 endif 622 return "=" 623endfun 624 625" test expression folding 626func Test_fold_expr() 627 new 628 set fdm=expr fde=Flvl() 629 630 let content = ['1 aa', 631 \ '2 bb', 632 \ '3 cc', 633 \ '4 dd {{{commentstart commentend', 634 \ '5 ee {{{ }}}', 635 \ '{{{', 636 \ '6 ff }}}', 637 \ '6 ff }}}', 638 \ ' 7 gg', 639 \ ' 8 hh', 640 \ '9 ii', 641 \ 'a jj', 642 \ 'b kk'] 643 call append(0, content) 644 call cursor(1, 1) 645 exe "normal /bb$\<CR>" 646 call assert_equal(2, foldlevel('.')) 647 exe "normal /hh$\<CR>" 648 call assert_equal(1, foldlevel('.')) 649 exe "normal /ii$\<CR>" 650 call assert_equal(2, foldlevel('.')) 651 exe "normal /kk$\<CR>" 652 call assert_equal(0, foldlevel('.')) 653 654 set fdm& fde& 655 bw! 656endfunc 657 658" Bug with fdm=indent and moving folds 659" Moving a fold a few times, messes up the folds below the moved fold. 660" Fixed by 7.4.700 661func Test_fold_move() 662 new 663 set fdm=indent sw=2 fdl=0 664 665 let content = ['', '', 'Line1', ' Line2', ' Line3', 666 \ 'Line4', ' Line5', ' Line6', 667 \ 'Line7', ' Line8', ' Line9'] 668 call append(0, content) 669 normal zM 670 call cursor(4, 1) 671 move 2 672 move 1 673 call assert_equal(7, foldclosed(7)) 674 call assert_equal(8, foldclosedend(7)) 675 call assert_equal(0, foldlevel(9)) 676 call assert_equal(10, foldclosed(10)) 677 call assert_equal(11, foldclosedend(10)) 678 call assert_equal('+-- 2 lines: Line2', foldtextresult(2)) 679 call assert_equal('+-- 2 lines: Line8', 10->foldtextresult()) 680 681 set fdm& sw& fdl& 682 bw! 683endfunc 684 685" test for patch 7.3.637 686" Cannot catch the error caused by a foldopen when there is no fold. 687func Test_foldopen_exception() 688 new 689 let a = 'No error caught' 690 try 691 foldopen 692 catch 693 let a = matchstr(v:exception,'^[^ ]*') 694 endtry 695 call assert_equal('Vim(foldopen):E490:', a) 696 697 let a = 'No error caught' 698 try 699 foobar 700 catch 701 let a = matchstr(v:exception,'^[^ ]*') 702 endtry 703 call assert_match('E492:', a) 704 bw! 705endfunc 706 707func Test_fold_last_line_with_pagedown() 708 new 709 set fdm=manual 710 711 let expect = '+-- 11 lines: 9---' 712 let content = range(1,19) 713 call append(0, content) 714 normal dd9G 715 normal zfG 716 normal zt 717 call assert_equal('9', getline(foldclosed('.'))) 718 call assert_equal('19', getline(foldclosedend('.'))) 719 call assert_equal(expect, ScreenLines(1, len(expect))[0]) 720 call feedkeys("\<C-F>", 'xt') 721 call assert_equal(expect, ScreenLines(1, len(expect))[0]) 722 call feedkeys("\<C-F>", 'xt') 723 call assert_equal(expect, ScreenLines(1, len(expect))[0]) 724 call feedkeys("\<C-B>\<C-F>\<C-F>", 'xt') 725 call assert_equal(expect, ScreenLines(1, len(expect))[0]) 726 727 set fdm& 728 bw! 729endfunc 730 731func Test_folds_with_rnu() 732 CheckScreendump 733 734 call writefile([ 735 \ 'set fdm=marker rnu foldcolumn=2', 736 \ 'call setline(1, ["{{{1", "nline 1", "{{{1", "line 2"])', 737 \ ], 'Xtest_folds_with_rnu') 738 let buf = RunVimInTerminal('-S Xtest_folds_with_rnu', {}) 739 740 call VerifyScreenDump(buf, 'Test_folds_with_rnu_01', {}) 741 call term_sendkeys(buf, "j") 742 call VerifyScreenDump(buf, 'Test_folds_with_rnu_02', {}) 743 744 " clean up 745 call StopVimInTerminal(buf) 746 call delete('Xtest_folds_with_rnu') 747endfunc 748 749func Test_folds_marker_in_comment2() 750 new 751 call setline(1, ['Lorem ipsum dolor sit', 'Lorem ipsum dolor sit', 'Lorem ipsum dolor sit']) 752 setl fen fdm=marker 753 setl commentstring=<!--%s--> 754 setl comments=s:<!--,m:\ \ \ \ ,e:--> 755 norm! zf2j 756 setl nofen 757 :1y 758 call assert_equal(['Lorem ipsum dolor sit<!--{{{-->'], getreg(0,1,1)) 759 :+2y 760 call assert_equal(['Lorem ipsum dolor sit<!--}}}-->'], getreg(0,1,1)) 761 762 set foldmethod& 763 bwipe! 764endfunc 765 766func Test_fold_delete_with_marker() 767 new 768 call setline(1, ['func Func() {{{1', 'endfunc']) 769 1,2yank 770 new 771 set fdm=marker 772 call setline(1, 'x') 773 normal! Vp 774 normal! zd 775 call assert_equal(['func Func() ', 'endfunc'], getline(1, '$')) 776 777 set fdm& 778 bwipe! 779 bwipe! 780endfunc 781 782func Test_fold_delete_with_marker_and_whichwrap() 783 new 784 let content1 = [''] 785 let content2 = ['folded line 1 "{{{1', ' test', ' test2', ' test3', '', 'folded line 2 "{{{1', ' test', ' test2', ' test3'] 786 call setline(1, content1 + content2) 787 set fdm=marker ww+=l 788 normal! x 789 call assert_equal(content2, getline(1, '$')) 790 set fdm& ww& 791 bwipe! 792endfunc 793 794func Test_fold_delete_first_line() 795 new 796 call setline(1, [ 797 \ '" x {{{1', 798 \ '" a', 799 \ '" aa', 800 \ '" x {{{1', 801 \ '" b', 802 \ '" bb', 803 \ '" x {{{1', 804 \ '" c', 805 \ '" cc', 806 \ ]) 807 set foldmethod=marker 808 1 809 normal dj 810 call assert_equal([ 811 \ '" x {{{1', 812 \ '" c', 813 \ '" cc', 814 \ ], getline(1,'$')) 815 bwipe! 816 set foldmethod& 817endfunc 818 819" Test for errors in 'foldexpr' 820func Test_fold_expr_error() 821 new 822 call setline(1, ['one', 'two', 'three']) 823 " In a window with no folds, foldlevel() should return 0 824 call assert_equal(0, foldlevel(1)) 825 826 " Return a list from the expression 827 set foldexpr=[] 828 set foldmethod=expr 829 for i in range(3) 830 call assert_equal(0, foldlevel(i)) 831 endfor 832 833 " expression error 834 set foldexpr=[{] 835 set foldmethod=expr 836 for i in range(3) 837 call assert_equal(0, foldlevel(i)) 838 endfor 839 840 set foldmethod& foldexpr& 841 close! 842endfunc 843 844func Test_undo_fold_deletion() 845 new 846 set fdm=marker 847 let lines =<< trim END 848 " {{{ 849 " }}}1 850 " {{{ 851 END 852 call setline(1, lines) 853 3d 854 g/"/d 855 undo 856 redo 857 eval getline(1, '$')->assert_equal(['']) 858 859 set fdm&vim 860 bwipe! 861endfunc 862 863" this was crashing 864func Test_move_no_folds() 865 new 866 fold 867 setlocal fdm=expr 868 normal zj 869 bwipe! 870endfunc 871 872" this was crashing 873func Test_fold_create_delete_create() 874 new 875 fold 876 fold 877 normal zd 878 fold 879 bwipe! 880endfunc 881 882" this was crashing 883func Test_fold_create_delete() 884 new 885 norm zFzFzdzj 886 bwipe! 887endfunc 888 889func Test_fold_relative_move() 890 new 891 set fdm=indent sw=2 wrap tw=80 892 893 let content = [ ' foo', ' bar', ' baz', 894 \ repeat('x', &columns + 1), 895 \ ' foo', ' bar', ' baz' 896 \ ] 897 call append(0, content) 898 899 normal zM 900 901 call cursor(3, 1) 902 call assert_true(foldclosed(line('.'))) 903 normal gj 904 call assert_equal(2, winline()) 905 906 call cursor(2, 1) 907 call assert_true(foldclosed(line('.'))) 908 normal 2gj 909 call assert_equal(3, winline()) 910 911 call cursor(5, 1) 912 call assert_true(foldclosed(line('.'))) 913 normal gk 914 call assert_equal(3, winline()) 915 916 call cursor(6, 1) 917 call assert_true(foldclosed(line('.'))) 918 normal 2gk 919 call assert_equal(2, winline()) 920 921 set fdm& sw& wrap& tw& 922 bw! 923endfunc 924 925" Test for using multibyte characters as 'foldopen', 'foldclose' and 926" 'foldsetp' items in 'fillchars' 927func s:mbyte_fillchar_tests(fo, fc, fs) 928 setlocal foldcolumn=3 929 930 normal zE 931 1,2fold 932 call assert_equal([a:fc .. ' +-- 2 ', ' three '], 933 \ ScreenLines([1, 2], 10)) 934 1,2foldopen 935 call assert_equal([a:fo .. ' one ', a:fs .. ' two '], 936 \ ScreenLines([1, 2], 7)) 937 1,2foldclose 938 redraw! 939 call assert_equal([a:fc .. ' +-- 2 ', ' three '], 940 \ ScreenLines([1, 2], 10)) 941 942 " Two level fold 943 normal zE 944 2,3fold 945 1,4fold 946 call assert_equal([a:fc .. ' +-- 4 ', ' five '], 947 \ ScreenLines([1, 2], 10)) 948 1,4foldopen 949 call assert_equal([a:fo .. ' one ', a:fs .. a:fc .. ' +--- 2'], 950 \ ScreenLines([1, 2], 10)) 951 1,4foldopen 952 call assert_equal([a:fo .. ' one ', a:fs .. a:fo .. ' two ', 953 \ a:fs .. a:fs .. ' three '], ScreenLines([1, 3], 10)) 954 2,3foldclose 955 call assert_equal([a:fo .. ' one ', a:fs .. a:fc .. ' +--- 2'], 956 \ ScreenLines([1, 2], 10)) 957 1,4foldclose 958 call assert_equal([a:fc .. ' +-- 4 ', ' five '], 959 \ ScreenLines([1, 2], 10)) 960 961 " Three level fold 962 normal zE 963 3,4fold 964 2,5fold 965 1,6fold 966 call assert_equal([a:fc .. ' +-- 6 '], ScreenLines(1, 10)) 967 " open all the folds 968 normal zR 969 call assert_equal([ 970 \ a:fo .. ' one ', 971 \ a:fs .. a:fo .. ' two ', 972 \ '2' .. a:fo .. ' three ', 973 \ '23 four ', 974 \ a:fs .. a:fs .. ' five ', 975 \ a:fs .. ' six ', 976 \ ], ScreenLines([1, 6], 10)) 977 " close the innermost fold 978 3,4foldclose 979 call assert_equal([ 980 \ a:fo .. ' one ', 981 \ a:fs .. a:fo .. ' two ', 982 \ a:fs .. a:fs .. a:fc .. '+---- ', 983 \ a:fs .. a:fs .. ' five ', 984 \ a:fs .. ' six ', 985 \ ], ScreenLines([1, 5], 10)) 986 " close the next fold 987 2,5foldclose 988 call assert_equal([ 989 \ a:fo .. ' one ', 990 \ a:fs .. a:fc .. ' +--- 4', 991 \ a:fs .. ' six ', 992 \ ], ScreenLines([1, 3], 10)) 993 994 " set the fold column size to 2 995 setlocal fdc=2 996 normal zR 997 call assert_equal([ 998 \ a:fo .. ' one ', 999 \ a:fo .. ' two ', 1000 \ a:fo .. ' three', 1001 \ '3 four ', 1002 \ '2 five ', 1003 \ a:fs .. ' six ', 1004 \ ], ScreenLines([1, 6], 7)) 1005 1006 " set the fold column size to 1 1007 setlocal fdc=1 1008 normal zR 1009 call assert_equal([ 1010 \ a:fo .. 'one ', 1011 \ a:fo .. 'two ', 1012 \ a:fo .. 'three ', 1013 \ '3four ', 1014 \ '2five ', 1015 \ a:fs .. 'six ', 1016 \ ], ScreenLines([1, 6], 7)) 1017 1018 " Enable number and sign columns and place some signs 1019 setlocal fdc=3 1020 setlocal number 1021 setlocal signcolumn=auto 1022 sign define S1 text=-> 1023 sign place 10 line=3 name=S1 1024 call assert_equal([ 1025 \ a:fo .. ' 1 one ', 1026 \ a:fs .. a:fo .. ' 2 two ', 1027 \ '2' .. a:fo .. ' -> 3 three', 1028 \ '23 4 four ', 1029 \ a:fs .. a:fs .. ' 5 five ', 1030 \ a:fs .. ' 6 six ' 1031 \ ], ScreenLines([1, 6], 14)) 1032 1033 " Test with 'rightleft' 1034 if has('rightleft') 1035 setlocal rightleft 1036 let lines = ScreenLines([1, 6], winwidth(0)) 1037 call assert_equal('o 1 ' .. a:fo, 1038 \ strcharpart(lines[0], strchars(lines[0]) - 10, 10)) 1039 call assert_equal('t 2 ' .. a:fo .. a:fs, 1040 \ strcharpart(lines[1], strchars(lines[1]) - 10, 10)) 1041 call assert_equal('t 3 >- ' .. a:fo .. '2', 1042 \ strcharpart(lines[2], strchars(lines[2]) - 10, 10)) 1043 call assert_equal('f 4 32', 1044 \ strcharpart(lines[3], strchars(lines[3]) - 10, 10)) 1045 call assert_equal('f 5 ' .. a:fs .. a:fs, 1046 \ strcharpart(lines[4], strchars(lines[4]) - 10, 10)) 1047 call assert_equal('s 6 ' .. a:fs, 1048 \ strcharpart(lines[5], strchars(lines[5]) - 10, 10)) 1049 setlocal norightleft 1050 endif 1051 1052 sign unplace * 1053 sign undefine S1 1054 setlocal number& signcolumn& 1055 1056 " Add a test with more than 9 folds (and then delete some folds) 1057 normal zE 1058 for i in range(1, 10) 1059 normal zfGzo 1060 endfor 1061 normal zR 1062 call assert_equal([ 1063 \ a:fo .. a:fo .. ' one ', 1064 \ '9> two ' 1065 \ ], ScreenLines([1, 2], 7)) 1066 normal 1Gzd 1067 call assert_equal([ 1068 \ a:fo .. a:fo .. ' one ', 1069 \ '89 two ' 1070 \ ], ScreenLines([1, 2], 7)) 1071 normal 1Gzdzdzdzdzdzdzd 1072 call assert_equal([ 1073 \ a:fo .. a:fo .. ' one ', 1074 \ a:fs .. a:fs .. ' two ' 1075 \ ], ScreenLines([1, 2], 7)) 1076 1077 setlocal foldcolumn& number& signcolumn& 1078endfunc 1079 1080func Test_foldcolumn_multibyte_char() 1081 new 1082 call setline(1, ['one', 'two', 'three', 'four', 'five', 'six']) 1083 setlocal foldenable foldmethod=manual 1084 1085 " First test with the default setting 1086 call s:mbyte_fillchar_tests('-', '+', '|') 1087 1088 " Use multi-byte characters 1089 set fillchars+=foldopen:▾,foldsep:│,foldclose:▸ 1090 call s:mbyte_fillchar_tests('▾', '▸', '│') 1091 1092 " Use a mix of multi-byte and single-byte characters 1093 set fillchars+=foldopen:¬,foldsep:\|,foldclose:+ 1094 call s:mbyte_fillchar_tests('¬', '+', '|') 1095 set fillchars+=foldopen:+,foldsep:\|,foldclose:¬ 1096 call s:mbyte_fillchar_tests('+', '¬', '|') 1097 1098 bw! 1099 set foldenable& fdc& fdm& fillchars& 1100endfunc 1101 1102" Test for calling foldlevel() from a fold expression 1103let g:FoldLevels = [] 1104func FoldExpr1(lnum) 1105 let f = [a:lnum] 1106 for i in range(1, line('$')) 1107 call add(f, foldlevel(i)) 1108 endfor 1109 call add(g:FoldLevels, f) 1110 return getline(a:lnum)[0] == "\t" 1111endfunc 1112 1113func Test_foldexpr_foldlevel() 1114 new 1115 call setline(1, ['one', "\ttwo", "\tthree"]) 1116 setlocal foldmethod=expr 1117 setlocal foldexpr=FoldExpr1(v:lnum) 1118 setlocal foldenable 1119 setlocal foldcolumn=3 1120 redraw! 1121 call assert_equal([[1, -1, -1, -1], [2, -1, -1, -1], [3, 0, 1, -1]], 1122 \ g:FoldLevels) 1123 set foldmethod& foldexpr& foldenable& foldcolumn& 1124 bw! 1125endfunc 1126 1127" Test for returning different values from a fold expression 1128func FoldExpr2(lnum) 1129 if a:lnum == 1 || a:lnum == 4 1130 return -2 1131 elseif a:lnum == 2 1132 return 'a1' 1133 elseif a:lnum == 3 1134 return 's4' 1135 endif 1136 return '=' 1137endfunc 1138 1139func Test_foldexpr_2() 1140 new 1141 call setline(1, ['one', 'two', 'three', 'four']) 1142 setlocal foldexpr=FoldExpr2(v:lnum) 1143 setlocal foldmethod=expr 1144 call assert_equal([0, 1, 1, 0], [foldlevel(1), foldlevel(2), foldlevel(3), 1145 \ foldlevel(4)]) 1146 bw! 1147endfunc 1148 1149" Test for the 'foldclose' option 1150func Test_foldclose_opt() 1151 CheckScreendump 1152 1153 let lines =<< trim END 1154 set foldmethod=manual foldclose=all foldopen=all 1155 call setline(1, ['one', 'two', 'three', 'four']) 1156 2,3fold 1157 func XsaveFoldLevels() 1158 redraw! 1159 call writefile([json_encode([foldclosed(1), foldclosed(2), foldclosed(3), 1160 \ foldclosed(4)])], 'Xoutput', 'a') 1161 endfunc 1162 END 1163 call writefile(lines, 'Xscript') 1164 let rows = 10 1165 let buf = RunVimInTerminal('-S Xscript', {'rows': rows}) 1166 call term_wait(buf) 1167 call term_sendkeys(buf, ":set noruler\n") 1168 call term_wait(buf) 1169 call term_sendkeys(buf, ":call XsaveFoldLevels()\n") 1170 call term_sendkeys(buf, "2G") 1171 call WaitForAssert({-> assert_equal('two', term_getline(buf, 2))}) 1172 call term_sendkeys(buf, ":call XsaveFoldLevels()\n") 1173 call term_sendkeys(buf, "4G") 1174 call WaitForAssert({-> assert_equal('four', term_getline(buf, 3))}) 1175 call term_sendkeys(buf, ":call XsaveFoldLevels()\n") 1176 call term_sendkeys(buf, "3G") 1177 call WaitForAssert({-> assert_equal('three', term_getline(buf, 3))}) 1178 call term_sendkeys(buf, ":call XsaveFoldLevels()\n") 1179 call term_sendkeys(buf, "1G") 1180 call WaitForAssert({-> assert_equal('four', term_getline(buf, 3))}) 1181 call term_sendkeys(buf, ":call XsaveFoldLevels()\n") 1182 1183 " clean up 1184 call StopVimInTerminal(buf) 1185 1186 call assert_equal(['[-1,2,2,-1]', '[-1,-1,-1,-1]', '[-1,2,2,-1]', 1187 \ '[-1,-1,-1,-1]', '[-1,2,2,-1]'], readfile('Xoutput')) 1188 call delete('Xscript') 1189 call delete('Xoutput') 1190endfunc 1191 1192" Test for foldtextresult() 1193func Test_foldtextresult() 1194 new 1195 call assert_equal('', foldtextresult(-1)) 1196 call assert_equal('', foldtextresult(0)) 1197 call assert_equal('', foldtextresult(1)) 1198 call setline(1, ['one', 'two', 'three', 'four']) 1199 2,3fold 1200 call assert_equal('', foldtextresult(1)) 1201 call assert_equal('+-- 2 lines: two', foldtextresult(2)) 1202 setlocal foldtext= 1203 call assert_equal('+-- 2 lines folded ', foldtextresult(2)) 1204 1205 " Fold text for a C comment fold 1206 %d _ 1207 setlocal foldtext& 1208 call setline(1, ['', '/*', ' * Comment', ' */', '']) 1209 2,4fold 1210 call assert_equal('+-- 3 lines: Comment', foldtextresult(2)) 1211 1212 bw! 1213endfunc 1214 1215" Test for merging two recursive folds when an intermediate line with no fold 1216" is removed 1217func Test_fold_merge_recrusive() 1218 new 1219 call setline(1, [' one', ' two', 'xxxx', ' three', 1220 \ ' four', "\tfive"]) 1221 setlocal foldmethod=indent shiftwidth=2 1222 3d_ 1223 %foldclose 1224 call assert_equal([1, 5], [foldclosed(5), foldclosedend(1)]) 1225 bw! 1226endfunc 1227 1228" Test for moving a line which is the start of a fold from a recursive fold to 1229" outside. The fold length should reduce. 1230func Test_fold_move_foldlevel() 1231 new 1232 call setline(1, ['a{{{', 'b{{{', 'c{{{', 'd}}}', 'e}}}', 'f}}}', 'g']) 1233 setlocal foldmethod=marker 1234 normal zR 1235 call assert_equal([3, 2, 1], [foldlevel(4), foldlevel(5), foldlevel(6)]) 1236 3move 7 1237 call assert_equal([2, 1, 0], [foldlevel(3), foldlevel(4), foldlevel(5)]) 1238 call assert_equal(1, foldlevel(7)) 1239 1240 " Move a line from outside a fold to inside the fold. 1241 %d _ 1242 call setline(1, ['a', 'b{{{', 'c}}}']) 1243 normal zR 1244 1move 2 1245 call assert_equal([1, 1, 1], [foldlevel(1), foldlevel(2), foldlevel(3)]) 1246 1247 " Move the start of one fold to inside another fold 1248 %d _ 1249 call setline(1, ['a', 'b{{{', 'c}}}', 'd{{{', 'e}}}']) 1250 normal zR 1251 call assert_equal([0, 1, 1, 1, 1], [foldlevel(1), foldlevel(2), 1252 \ foldlevel(3), foldlevel(4), foldlevel(5)]) 1253 1,2move 4 1254 call assert_equal([0, 1, 1, 2, 2], [foldlevel(1), foldlevel(2), 1255 \ foldlevel(3), foldlevel(4), foldlevel(5)]) 1256 1257 bw! 1258endfunc 1259 1260" vim: shiftwidth=2 sts=2 expandtab 1261