test_diffmode.vim (107415B)
1 " Tests for diff mode 2 3 source shared.vim 4 source screendump.vim 5 source check.vim 6 source view_util.vim 7 8 func Test_diff_fold_sync() 9 enew! 10 let g:update_count = 0 11 au DiffUpdated * let g:update_count += 1 12 13 let l = range(50) 14 call setline(1, l) 15 diffthis 16 let winone = win_getid() 17 new 18 let l[25] = 'diff' 19 call setline(1, l) 20 diffthis 21 let wintwo = win_getid() 22 " line 15 is inside the closed fold 23 call assert_equal(19, foldclosedend(10)) 24 call win_gotoid(winone) 25 call assert_equal(19, foldclosedend(10)) 26 " open the fold 27 normal zv 28 call assert_equal(-1, foldclosedend(10)) 29 " fold in other window must have opened too 30 call win_gotoid(wintwo) 31 call assert_equal(-1, foldclosedend(10)) 32 33 " cursor position is in sync 34 normal 23G 35 call win_gotoid(winone) 36 call assert_equal(23, getcurpos()[1]) 37 38 " depending on how redraw is done DiffUpdated may be triggered once or twice 39 call assert_inrange(1, 2, g:update_count) 40 au! DiffUpdated 41 42 windo diffoff 43 close! 44 set nomodified 45 endfunc 46 47 func Test_vert_split() 48 set diffopt=filler 49 call Common_vert_split() 50 set diffopt& 51 endfunc 52 53 " Test for diff folding redraw after last diff is resolved 54 func Test_diff_fold_redraw() 55 " Set up two files with a minimal case. 56 call writefile(['Paragraph 1', '', 'Paragraph 2', '', 'Paragraph 3'], 'Xfile1') 57 call writefile(['Paragraph 1', '', 'Paragraph 3'], 'Xfile2') 58 59 " Open in diff mode. 60 edit Xfile1 61 vert diffsplit Xfile2 62 63 " Go to the diff and apply :diffput to copy Paragraph 2 to Xfile2. 64 wincmd l 65 3 66 diffput 67 68 " Check that the folds in both windows are closed and extend from the first 69 " line of the buffer to the last line of the buffer. 70 call assert_equal(1, foldclosed(line("$"))) 71 wincmd h 72 call assert_equal(1, foldclosed(line("$"))) 73 74 " Clean up. 75 bwipe! 76 bwipe! 77 call delete('Xfile1') 78 call delete('Xfile2') 79 endfunc 80 81 func Test_vert_split_internal() 82 set diffopt=internal,filler 83 call Common_vert_split() 84 set diffopt& 85 endfunc 86 87 func Common_vert_split() 88 " Disable the title to avoid xterm keeping the wrong one. 89 set notitle noicon 90 new 91 let l = ['1 aa', '2 bb', '3 cc', '4 dd', '5 ee'] 92 call setline(1, l) 93 w! Xtest 94 normal dd 95 $ 96 put 97 normal kkrXoxxx 98 w! Xtest2 99 file Nop 100 normal ggoyyyjjjozzzz 101 set foldmethod=marker foldcolumn=4 102 call assert_equal(0, &diff) 103 call assert_equal('marker', &foldmethod) 104 call assert_equal('4', &foldcolumn) 105 call assert_equal(0, &scrollbind) 106 call assert_equal(0, &cursorbind) 107 call assert_equal(1, &wrap) 108 109 vert diffsplit Xtest 110 vert diffsplit Xtest2 111 call assert_equal(1, &diff) 112 call assert_equal('diff', &foldmethod) 113 call assert_equal('2', &foldcolumn) 114 call assert_equal(1, &scrollbind) 115 call assert_equal(1, &cursorbind) 116 call assert_equal(0, &wrap) 117 118 let diff_fdm = &fdm 119 let diff_fdc = &fdc 120 " repeat entering diff mode here to see if this saves the wrong settings 121 diffthis 122 " jump to second window for a moment to have filler line appear at start of 123 " first window 124 wincmd w 125 normal gg 126 wincmd p 127 normal gg 128 call assert_equal(2, winline()) 129 normal j 130 call assert_equal(4, winline()) 131 normal j 132 call assert_equal(5, winline()) 133 normal j 134 call assert_equal(6, winline()) 135 normal j 136 call assert_equal(8, winline()) 137 normal j 138 call assert_equal(9, winline()) 139 140 wincmd w 141 normal gg 142 call assert_equal(1, winline()) 143 normal j 144 call assert_equal(2, winline()) 145 normal j 146 call assert_equal(4, winline()) 147 normal j 148 call assert_equal(5, winline()) 149 normal j 150 call assert_equal(8, winline()) 151 152 wincmd w 153 normal gg 154 call assert_equal(2, winline()) 155 normal j 156 call assert_equal(3, winline()) 157 normal j 158 call assert_equal(4, winline()) 159 normal j 160 call assert_equal(5, winline()) 161 normal j 162 call assert_equal(6, winline()) 163 normal j 164 call assert_equal(7, winline()) 165 normal j 166 call assert_equal(8, winline()) 167 168 " Test diffoff 169 diffoff! 170 1wincmd w 171 let &diff = 1 172 let &fdm = diff_fdm 173 let &fdc = diff_fdc 174 4wincmd w 175 diffoff! 176 1wincmd w 177 call assert_equal(0, &diff) 178 call assert_equal('marker', &foldmethod) 179 call assert_equal('4', &foldcolumn) 180 call assert_equal(0, &scrollbind) 181 call assert_equal(0, &cursorbind) 182 call assert_equal(1, &wrap) 183 184 wincmd w 185 call assert_equal(0, &diff) 186 call assert_equal('marker', &foldmethod) 187 call assert_equal('4', &foldcolumn) 188 call assert_equal(0, &scrollbind) 189 call assert_equal(0, &cursorbind) 190 call assert_equal(1, &wrap) 191 192 wincmd w 193 call assert_equal(0, &diff) 194 call assert_equal('marker', &foldmethod) 195 call assert_equal('4', &foldcolumn) 196 call assert_equal(0, &scrollbind) 197 call assert_equal(0, &cursorbind) 198 call assert_equal(1, &wrap) 199 200 call delete('Xtest') 201 call delete('Xtest2') 202 windo bw! 203 endfunc 204 205 func Test_filler_lines() 206 " Test that diffing shows correct filler lines 207 enew! 208 put =range(4,10) 209 1d _ 210 vnew 211 put =range(1,10) 212 1d _ 213 windo diffthis 214 wincmd h 215 call assert_equal(1, line('w0')) 216 unlet! diff_fdm diff_fdc 217 windo diffoff 218 bwipe! 219 enew! 220 endfunc 221 222 func Test_diffget_diffput() 223 enew! 224 let l = range(50) 225 call setline(1, l) 226 call assert_fails('diffget', 'E99:') 227 diffthis 228 call assert_fails('diffget', 'E100:') 229 new 230 let l[10] = 'one' 231 let l[20] = 'two' 232 let l[30] = 'three' 233 let l[40] = 'four' 234 call setline(1, l) 235 diffthis 236 call assert_equal('one', getline(11)) 237 11diffget 238 call assert_equal('10', getline(11)) 239 21diffput 240 wincmd w 241 call assert_equal('two', getline(21)) 242 normal 31Gdo 243 call assert_equal('three', getline(31)) 244 call assert_equal('40', getline(41)) 245 normal 41Gdp 246 wincmd w 247 call assert_equal('40', getline(41)) 248 new 249 diffthis 250 call assert_fails('diffget', 'E101:') 251 252 windo diffoff 253 %bwipe! 254 endfunc 255 256 " Test putting two changes from one buffer to another 257 func Test_diffput_two() 258 new a 259 let win_a = win_getid() 260 call setline(1, range(1, 10)) 261 diffthis 262 new b 263 let win_b = win_getid() 264 call setline(1, range(1, 10)) 265 8del 266 5del 267 diffthis 268 call win_gotoid(win_a) 269 %diffput 270 call win_gotoid(win_b) 271 call assert_equal(map(range(1, 10), 'string(v:val)'), getline(1, '$')) 272 bwipe! a 273 bwipe! b 274 endfunc 275 276 " Test for :diffget/:diffput with a range that is inside a diff chunk 277 func Test_diffget_diffput_range() 278 call setline(1, range(1, 10)) 279 new 280 call setline(1, range(11, 20)) 281 windo diffthis 282 3,5diffget 283 call assert_equal(['13', '14', '15'], getline(3, 5)) 284 call setline(1, range(1, 10)) 285 4,8diffput 286 wincmd p 287 call assert_equal(['13', '4', '5', '6', '7', '8', '19'], getline(3, 9)) 288 %bw! 289 endfunc 290 291 " Test :diffget/:diffput handling of added/deleted lines 292 func Test_diffget_diffput_deleted_lines() 293 call setline(1, ['2','4','6']) 294 diffthis 295 new 296 call setline(1, range(1,7)) 297 diffthis 298 wincmd w 299 300 3,3diffget " get nothing 301 call assert_equal(['2', '4', '6'], getline(1, '$')) 302 3,4diffget " get the last insertion past the end of file 303 call assert_equal(['2', '4', '6', '7'], getline(1, '$')) 304 0,1diffget " get the first insertion above first line 305 call assert_equal(['1', '2', '4', '6', '7'], getline(1, '$')) 306 307 " When using non-range diffget on the last line, it should get the 308 " change above or at the line as usual, but if the only change is below the 309 " last line, diffget should get that instead. 310 1,$delete 311 call setline(1, ['2','4','6']) 312 diffupdate 313 norm Gdo 314 call assert_equal(['2', '4', '5', '6'], getline(1, '$')) 315 norm Gdo 316 call assert_equal(['2', '4', '5', '6', '7'], getline(1, '$')) 317 318 " Test non-range diffput on last line with the same logic 319 1,$delete 320 call setline(1, ['2','4','6']) 321 diffupdate 322 norm Gdp 323 wincmd w 324 call assert_equal(['1', '2', '3', '4', '6', '7'], getline(1, '$')) 325 wincmd w 326 norm Gdp 327 wincmd w 328 call assert_equal(['1', '2', '3', '4', '6'], getline(1, '$')) 329 call setline(1, range(1,7)) 330 diffupdate 331 wincmd w 332 333 " Test that 0,$+1 will get/put all changes from/to the other buffer 334 1,$delete 335 call setline(1, ['2','4','6']) 336 diffupdate 337 0,$+1diffget 338 call assert_equal(['1', '2', '3', '4', '5', '6', '7'], getline(1, '$')) 339 1,$delete 340 call setline(1, ['2','4','6']) 341 diffupdate 342 0,$+1diffput 343 wincmd w 344 call assert_equal(['2', '4', '6'], getline(1, '$')) 345 %bw! 346 endfunc 347 348 " Test for :diffget/:diffput with an empty buffer and a non-empty buffer 349 func Test_diffget_diffput_empty_buffer() 350 %d _ 351 new 352 call setline(1, 'one') 353 windo diffthis 354 diffget 355 call assert_equal(['one'], getline(1, '$')) 356 %d _ 357 diffput 358 wincmd p 359 call assert_equal([''], getline(1, '$')) 360 %bw! 361 endfunc 362 363 " :diffput and :diffget completes names of buffers which 364 " are in diff mode and which are different than current buffer. 365 " No completion when the current window is not in diff mode. 366 func Test_diffget_diffput_completion() 367 e Xdiff1 | diffthis 368 botright new Xdiff2 369 botright new Xdiff3 | split | diffthis 370 botright new Xdiff4 | diffthis 371 372 wincmd t 373 call assert_equal('Xdiff1', bufname('%')) 374 call feedkeys(":diffput \<C-A>\<C-B>\"\<CR>", 'tx') 375 call assert_equal('"diffput Xdiff3 Xdiff4', @:) 376 call feedkeys(":diffget \<C-A>\<C-B>\"\<CR>", 'tx') 377 call assert_equal('"diffget Xdiff3 Xdiff4', @:) 378 call assert_equal(['Xdiff3', 'Xdiff4'], getcompletion('', 'diff_buffer')) 379 380 " Xdiff2 is not in diff mode, so no completion for :diffput, :diffget 381 wincmd j 382 call assert_equal('Xdiff2', bufname('%')) 383 call feedkeys(":diffput \<C-A>\<C-B>\"\<CR>", 'tx') 384 call assert_equal('"diffput ', @:) 385 call feedkeys(":diffget \<C-A>\<C-B>\"\<CR>", 'tx') 386 call assert_equal('"diffget ', @:) 387 call assert_equal([], getcompletion('', 'diff_buffer')) 388 389 " Xdiff3 is split in 2 windows, only the top one is in diff mode. 390 " So completion of :diffput :diffget only happens in the top window. 391 wincmd j 392 call assert_equal('Xdiff3', bufname('%')) 393 call assert_equal(1, &diff) 394 call feedkeys(":diffput \<C-A>\<C-B>\"\<CR>", 'tx') 395 call assert_equal('"diffput Xdiff1 Xdiff4', @:) 396 call feedkeys(":diffget \<C-A>\<C-B>\"\<CR>", 'tx') 397 call assert_equal('"diffget Xdiff1 Xdiff4', @:) 398 call assert_equal(['Xdiff1', 'Xdiff4'], getcompletion('', 'diff_buffer')) 399 400 wincmd j 401 call assert_equal('Xdiff3', bufname('%')) 402 call assert_equal(0, &diff) 403 call feedkeys(":diffput \<C-A>\<C-B>\"\<CR>", 'tx') 404 call assert_equal('"diffput ', @:) 405 call feedkeys(":diffget \<C-A>\<C-B>\"\<CR>", 'tx') 406 call assert_equal('"diffget ', @:) 407 call assert_equal([], getcompletion('', 'diff_buffer')) 408 409 wincmd j 410 call assert_equal('Xdiff4', bufname('%')) 411 call feedkeys(":diffput \<C-A>\<C-B>\"\<CR>", 'tx') 412 call assert_equal('"diffput Xdiff1 Xdiff3', @:) 413 call feedkeys(":diffget \<C-A>\<C-B>\"\<CR>", 'tx') 414 call assert_equal('"diffget Xdiff1 Xdiff3', @:) 415 call assert_equal(['Xdiff1', 'Xdiff3'], getcompletion('', 'diff_buffer')) 416 417 %bwipe 418 endfunc 419 420 func Test_dp_do_buffer() 421 e! one 422 let bn1=bufnr('%') 423 let l = range(60) 424 call setline(1, l) 425 diffthis 426 427 new two 428 let l[10] = 'one' 429 let l[20] = 'two' 430 let l[30] = 'three' 431 let l[40] = 'four' 432 let l[50] = 'five' 433 call setline(1, l) 434 diffthis 435 436 " dp and do with invalid buffer number. 437 11 438 call assert_fails('norm 99999dp', 'E102:') 439 call assert_fails('norm 99999do', 'E102:') 440 call assert_fails('diffput non_existing_buffer', 'E94:') 441 call assert_fails('diffget non_existing_buffer', 'E94:') 442 443 " dp and do with valid buffer number. 444 call assert_equal('one', getline('.')) 445 exe 'norm ' . bn1 . 'do' 446 call assert_equal('10', getline('.')) 447 21 448 call assert_equal('two', getline('.')) 449 diffget one 450 call assert_equal('20', getline('.')) 451 452 31 453 exe 'norm ' . bn1 . 'dp' 454 41 455 diffput one 456 wincmd w 457 31 458 call assert_equal('three', getline('.')) 459 41 460 call assert_equal('four', getline('.')) 461 462 " dp and do with buffer number which is not in diff mode. 463 new not_in_diff_mode 464 let bn3=bufnr('%') 465 wincmd w 466 51 467 call assert_fails('exe "norm" . bn3 . "dp"', 'E103:') 468 call assert_fails('exe "norm" . bn3 . "do"', 'E103:') 469 call assert_fails('diffput not_in_diff_mode', 'E94:') 470 call assert_fails('diffget not_in_diff_mode', 'E94:') 471 472 windo diffoff 473 %bwipe! 474 endfunc 475 476 func Test_do_lastline() 477 e! one 478 call setline(1, ['1','2','3','4','5','6']) 479 diffthis 480 481 new two 482 call setline(1, ['2','4','5']) 483 diffthis 484 485 1 486 norm dp]c 487 norm dp]c 488 wincmd w 489 call assert_equal(4, line('$')) 490 norm G 491 norm do 492 call assert_equal(3, line('$')) 493 494 windo diffoff 495 %bwipe! 496 endfunc 497 498 func Test_diffoff() 499 enew! 500 call setline(1, ['Two', 'Three']) 501 redraw 502 let normattr = screenattr(1, 1) 503 diffthis 504 botright vert new 505 call setline(1, ['One', '', 'Two', 'Three']) 506 diffthis 507 redraw 508 call assert_notequal(normattr, 1->screenattr(1)) 509 diffoff! 510 redraw 511 call assert_equal(normattr, screenattr(1, 1)) 512 bwipe! 513 bwipe! 514 endfunc 515 516 func Common_icase_test() 517 edit one 518 call setline(1, ['One', 'Two', 'Three', 'Four', 'Fi#vϵ', 'Si⃗x', 'Se⃗ve⃗n']) 519 redraw 520 let normattr = screenattr(1, 1) 521 diffthis 522 523 botright vert new two 524 call setline(1, ['one', 'TWO', 'Three ', 'Four', 'fI=VΕ', 'SI⃗x', 'SEvE⃗n']) 525 diffthis 526 527 redraw 528 call assert_equal(normattr, screenattr(1, 1)) 529 call assert_equal(normattr, screenattr(2, 1)) 530 call assert_notequal(normattr, screenattr(3, 1)) 531 call assert_equal(normattr, screenattr(4, 1)) 532 call assert_equal(normattr, screenattr(6, 2)) 533 call assert_notequal(normattr, screenattr(7, 2)) 534 535 let dtextattr = screenattr(5, 3) 536 call assert_notequal(dtextattr, screenattr(5, 1)) 537 call assert_notequal(dtextattr, screenattr(5, 5)) 538 call assert_notequal(dtextattr, screenattr(7, 4)) 539 540 diffoff! 541 %bwipe! 542 endfunc 543 544 func Test_diffopt_icase() 545 set diffopt=icase,foldcolumn:0 546 call Common_icase_test() 547 set diffopt& 548 endfunc 549 550 func Test_diffopt_icase_internal() 551 set diffopt=icase,foldcolumn:0,internal 552 call Common_icase_test() 553 set diffopt& 554 endfunc 555 556 func Common_iwhite_test() 557 edit one 558 " Difference in trailing spaces and amount of spaces should be ignored, 559 " but not other space differences. 560 call setline(1, ["One \t", 'Two', 'Three', 'one two', 'one two', 'Four']) 561 redraw 562 let normattr = screenattr(1, 1) 563 diffthis 564 565 botright vert new two 566 call setline(1, ["One\t ", "Two\t ", 'Three', 'one two', 'onetwo', ' Four']) 567 diffthis 568 569 redraw 570 call assert_equal(normattr, screenattr(1, 1)) 571 call assert_equal(normattr, screenattr(2, 1)) 572 call assert_equal(normattr, screenattr(3, 1)) 573 call assert_equal(normattr, screenattr(4, 1)) 574 call assert_notequal(normattr, screenattr(5, 1)) 575 call assert_notequal(normattr, screenattr(6, 1)) 576 577 diffoff! 578 %bwipe! 579 endfunc 580 581 func Test_diffopt_iwhite() 582 set diffopt=iwhite,foldcolumn:0 583 call Common_iwhite_test() 584 set diffopt& 585 endfunc 586 587 func Test_diffopt_iwhite_internal() 588 set diffopt=internal,iwhite,foldcolumn:0 589 call Common_iwhite_test() 590 set diffopt& 591 endfunc 592 593 func Test_diffopt_context() 594 enew! 595 call setline(1, ['1', '2', '3', '4', '5', '6', '7']) 596 diffthis 597 new 598 call setline(1, ['1', '2', '3', '4', '5x', '6', '7']) 599 diffthis 600 601 set diffopt=context:2 602 call assert_equal('+-- 2 lines: 1', foldtextresult(1)) 603 set diffopt=internal,context:2 604 call assert_equal('+-- 2 lines: 1', foldtextresult(1)) 605 606 set diffopt=context:1 607 call assert_equal('+-- 3 lines: 1', foldtextresult(1)) 608 set diffopt=internal,context:1 609 call assert_equal('+-- 3 lines: 1', foldtextresult(1)) 610 611 diffoff! 612 %bwipe! 613 set diffopt& 614 endfunc 615 616 func Test_diffopt_horizontal() 617 set diffopt=internal,horizontal 618 diffsplit 619 620 call assert_equal(&columns, winwidth(1)) 621 call assert_equal(&columns, winwidth(2)) 622 call assert_equal(&lines, winheight(1) + winheight(2) + 3) 623 call assert_inrange(0, 1, winheight(1) - winheight(2)) 624 625 set diffopt& 626 diffoff! 627 %bwipe 628 endfunc 629 630 func Test_diffopt_vertical() 631 set diffopt=internal,vertical 632 diffsplit 633 634 call assert_equal(&lines - 2, winheight(1)) 635 call assert_equal(&lines - 2, winheight(2)) 636 call assert_equal(&columns, winwidth(1) + winwidth(2) + 1) 637 call assert_inrange(0, 1, winwidth(1) - winwidth(2)) 638 639 set diffopt& 640 diffoff! 641 %bwipe 642 endfunc 643 644 func Test_diffopt_hiddenoff() 645 set diffopt=internal,filler,foldcolumn:0,hiddenoff 646 e! one 647 call setline(1, ['Two', 'Three']) 648 redraw 649 let normattr = screenattr(1, 1) 650 diffthis 651 botright vert new two 652 call setline(1, ['One', 'Four']) 653 diffthis 654 redraw 655 call assert_notequal(normattr, screenattr(1, 1)) 656 set hidden 657 close 658 redraw 659 " should not diffing with hidden buffer two while 'hiddenoff' is enabled 660 call assert_equal(normattr, screenattr(1, 1)) 661 662 bwipe! 663 bwipe! 664 set hidden& diffopt& 665 endfunc 666 667 func Test_diffoff_hidden() 668 set diffopt=internal,filler,foldcolumn:0 669 e! one 670 call setline(1, ['Two', 'Three']) 671 redraw 672 let normattr = screenattr(1, 1) 673 diffthis 674 botright vert new two 675 call setline(1, ['One', 'Four']) 676 diffthis 677 redraw 678 call assert_notequal(normattr, screenattr(1, 1)) 679 set hidden 680 close 681 redraw 682 " diffing with hidden buffer two 683 call assert_notequal(normattr, screenattr(1, 1)) 684 diffoff 685 redraw 686 call assert_equal(normattr, screenattr(1, 1)) 687 diffthis 688 redraw 689 " still diffing with hidden buffer two 690 call assert_notequal(normattr, screenattr(1, 1)) 691 diffoff! 692 redraw 693 call assert_equal(normattr, screenattr(1, 1)) 694 diffthis 695 redraw 696 " no longer diffing with hidden buffer two 697 call assert_equal(normattr, screenattr(1, 1)) 698 699 bwipe! 700 bwipe! 701 set hidden& diffopt& 702 endfunc 703 704 func Test_setting_cursor() 705 new Xtest1 706 put =range(1,90) 707 wq 708 new Xtest2 709 put =range(1,100) 710 wq 711 712 tabe Xtest2 713 $ 714 diffsp Xtest1 715 tabclose 716 717 call delete('Xtest1') 718 call delete('Xtest2') 719 endfunc 720 721 func Test_diff_move_to() 722 new 723 call setline(1, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) 724 diffthis 725 vnew 726 call setline(1, [1, '2x', 3, 4, 4, 5, '6x', 7, '8x', 9, '10x']) 727 diffthis 728 norm ]c 729 call assert_equal(2, line('.')) 730 norm 3]c 731 call assert_equal(9, line('.')) 732 norm 10]c 733 call assert_equal(11, line('.')) 734 norm [c 735 call assert_equal(9, line('.')) 736 norm 2[c 737 call assert_equal(5, line('.')) 738 norm 10[c 739 call assert_equal(2, line('.')) 740 %bwipe! 741 endfunc 742 743 func Test_diffexpr() 744 CheckExecutable diff 745 746 func DiffExpr() 747 " Prepend some text to check diff type detection 748 call writefile(['warning', ' message'], v:fname_out) 749 silent exe '!diff ' . v:fname_in . ' ' . v:fname_new . '>>' . v:fname_out 750 endfunc 751 set diffexpr=DiffExpr() 752 set diffopt=foldcolumn:0 753 754 enew! 755 call setline(1, ['one', 'two', 'three']) 756 redraw 757 let normattr = screenattr(1, 1) 758 diffthis 759 760 botright vert new 761 call setline(1, ['one', 'two', 'three.']) 762 diffthis 763 764 redraw 765 call assert_equal(normattr, screenattr(1, 1)) 766 call assert_equal(normattr, screenattr(2, 1)) 767 call assert_notequal(normattr, screenattr(3, 1)) 768 diffoff! 769 770 " Try using a non-existing function for 'diffexpr'. 771 set diffexpr=NewDiffFunc() 772 call assert_fails('windo diffthis', ['E117:', 'E97:']) 773 diffoff! 774 775 " Using a script-local function 776 func s:NewDiffExpr() 777 endfunc 778 set diffexpr=s:NewDiffExpr() 779 call assert_equal(expand('<SID>') .. 'NewDiffExpr()', &diffexpr) 780 set diffexpr=<SID>NewDiffExpr() 781 call assert_equal(expand('<SID>') .. 'NewDiffExpr()', &diffexpr) 782 783 %bwipe! 784 set diffexpr& diffopt& 785 delfunc DiffExpr 786 delfunc s:NewDiffExpr 787 endfunc 788 789 func Test_diffpatch() 790 " The patch program on MS-Windows may fail or hang. 791 CheckExecutable patch 792 CheckUnix 793 new 794 insert 795 *************** 796 *** 1,3 **** 797 1 798 ! 2 799 3 800 --- 1,4 ---- 801 1 802 ! 2x 803 3 804 + 4 805 . 806 saveas! Xpatch 807 bwipe! 808 new 809 call assert_fails('diffpatch Xpatch', 'E816:') 810 811 for name in ['Xpatch', 'Xpatch$HOME', 'Xpa''tch'] 812 call setline(1, ['1', '2', '3']) 813 if name != 'Xpatch' 814 call rename('Xpatch', name) 815 endif 816 exe 'diffpatch ' . escape(name, '$') 817 call assert_equal(['1', '2x', '3', '4'], getline(1, '$')) 818 if name != 'Xpatch' 819 call rename(name, 'Xpatch') 820 endif 821 bwipe! 822 endfor 823 824 call delete('Xpatch') 825 bwipe! 826 endfunc 827 828 func Test_diff_too_many_buffers() 829 for i in range(1, 8) 830 exe "new Xtest" . i 831 diffthis 832 endfor 833 new Xtest9 834 call assert_fails('diffthis', 'E96:') 835 %bwipe! 836 endfunc 837 838 func Test_diff_nomodifiable() 839 new 840 call setline(1, [1, 2, 3, 4]) 841 setl nomodifiable 842 diffthis 843 vnew 844 call setline(1, ['1x', 2, 3, 3, 4]) 845 diffthis 846 call assert_fails('norm dp', 'E793:') 847 setl nomodifiable 848 call assert_fails('norm do', 'E21:') 849 %bwipe! 850 endfunc 851 852 func Test_diff_hlID() 853 set diffopt=internal,filler 854 new 855 call setline(1, [1, 2, 3, 'Yz', 'a dxxg',]) 856 diffthis 857 vnew 858 call setline(1, ['1x', 2, 'x', 3, 'yx', 'abc defg']) 859 diffthis 860 redraw 861 862 call diff_hlID(-1, 1)->synIDattr("name")->assert_equal("") 863 864 call diff_hlID(1, 1)->synIDattr("name")->assert_equal("DiffChange") 865 call diff_hlID(1, 2)->synIDattr("name")->assert_equal("DiffText") 866 call diff_hlID(2, 1)->synIDattr("name")->assert_equal("") 867 call diff_hlID(3, 1)->synIDattr("name")->assert_equal("DiffAdd") 868 eval 4->diff_hlID(1)->synIDattr("name")->assert_equal("") 869 call diff_hlID(5, 1)->synIDattr("name")->assert_equal("DiffText") 870 call diff_hlID(5, 2)->synIDattr("name")->assert_equal("DiffText") 871 872 set diffopt+=icase " test that caching is invalidated by diffopt change 873 call diff_hlID(5, 1)->synIDattr("name")->assert_equal("DiffChange") 874 set diffopt-=icase 875 call diff_hlID(5, 1)->synIDattr("name")->assert_equal("DiffText") 876 877 call diff_hlID(6, 1)->synIDattr("name")->assert_equal("DiffChange") 878 call diff_hlID(6, 2)->synIDattr("name")->assert_equal("DiffText") 879 call diff_hlID(6, 4)->synIDattr("name")->assert_equal("DiffText") 880 call diff_hlID(6, 7)->synIDattr("name")->assert_equal("DiffText") 881 call diff_hlID(6, 8)->synIDattr("name")->assert_equal("DiffChange") 882 set diffopt+=inline:char 883 call diff_hlID(6, 1)->synIDattr("name")->assert_equal("DiffChange") 884 call diff_hlID(6, 2)->synIDattr("name")->assert_equal("DiffTextAdd") 885 call diff_hlID(6, 4)->synIDattr("name")->assert_equal("DiffChange") 886 call diff_hlID(6, 7)->synIDattr("name")->assert_equal("DiffText") 887 call diff_hlID(6, 8)->synIDattr("name")->assert_equal("DiffChange") 888 set diffopt-=inline:char 889 890 wincmd w 891 call assert_equal(synIDattr(diff_hlID(1, 1), "name"), "DiffChange") 892 call assert_equal(synIDattr(diff_hlID(2, 1), "name"), "") 893 call assert_equal(synIDattr(diff_hlID(3, 1), "name"), "") 894 895 %bwipe! 896 set diffopt& 897 endfunc 898 899 func Test_diff_filler() 900 new 901 call setline(1, [1, 2, 3, 'x', 4]) 902 diffthis 903 vnew 904 call setline(1, [1, 2, 'y', 'y', 3, 4]) 905 diffthis 906 redraw 907 908 call assert_equal([0, 0, 0, 0, 0, 0, 0, 1, 0], map(range(-1, 7), 'v:val->diff_filler()')) 909 wincmd w 910 call assert_equal([0, 0, 0, 0, 2, 0, 0, 0], map(range(-1, 6), 'diff_filler(v:val)')) 911 912 %bwipe! 913 endfunc 914 915 func Test_diff_lastline() 916 enew! 917 only! 918 call setline(1, ['This is a ', 'line with five ', 'rows']) 919 diffthis 920 botright vert new 921 call setline(1, ['This is', 'a line with ', 'four rows']) 922 diffthis 923 1 924 call feedkeys("Je a\<CR>", 'tx') 925 call feedkeys("Je a\<CR>", 'tx') 926 let w1lines = winline() 927 wincmd w 928 $ 929 let w2lines = winline() 930 call assert_equal(w2lines, w1lines) 931 bwipe! 932 bwipe! 933 endfunc 934 935 func WriteDiffFiles(buf, list1, list2) 936 call writefile(a:list1, 'Xdifile1') 937 call writefile(a:list2, 'Xdifile2') 938 if a:buf 939 call term_sendkeys(a:buf, ":checktime\<CR>") 940 endif 941 endfunc 942 943 func WriteDiffFiles3(buf, list1, list2, list3) 944 call writefile(a:list1, 'Xdifile1') 945 call writefile(a:list2, 'Xdifile2') 946 call writefile(a:list3, 'Xdifile3') 947 if a:buf 948 call term_sendkeys(a:buf, ":checktime\<CR>") 949 endif 950 endfunc 951 952 " Verify a screendump with both the internal and external diff. 953 func VerifyBoth(buf, dumpfile, extra) 954 CheckScreendump 955 956 " trailing : for leaving the cursor on the command line 957 for cmd in [":set diffopt=filler" . a:extra . "\<CR>:", ":set diffopt+=internal\<CR>:"] 958 call term_sendkeys(a:buf, cmd) 959 if VerifyScreenDump(a:buf, a:dumpfile, {}, cmd =~ 'internal' ? 'internal' : 'external') 960 break " don't let the next iteration overwrite the "failed" file. 961 " don't let the next iteration overwrite the "failed" file. 962 return 963 endif 964 endfor 965 966 " also test unified diff 967 call term_sendkeys(a:buf, ":call SetupUnified()\<CR>:") 968 call term_sendkeys(a:buf, ":redraw!\<CR>:") 969 call VerifyScreenDump(a:buf, a:dumpfile, {}, 'unified') 970 call term_sendkeys(a:buf, ":call StopUnified()\<CR>:") 971 endfunc 972 973 " Verify a screendump with the internal diff only. 974 func VerifyInternal(buf, dumpfile, extra) 975 CheckScreendump 976 977 call term_sendkeys(a:buf, ":diffupdate!\<CR>") 978 " trailing : for leaving the cursor on the command line 979 call term_sendkeys(a:buf, ":set diffopt=internal,filler" . a:extra . "\<CR>:") 980 call VerifyScreenDump(a:buf, a:dumpfile, {}) 981 endfunc 982 983 func Test_diff_screen() 984 let g:test_is_flaky = 1 985 CheckScreendump 986 CheckFeature menu 987 988 let lines =<< trim END 989 func UnifiedDiffExpr() 990 " Prepend some text to check diff type detection 991 call writefile(['warning', ' message'], v:fname_out) 992 silent exe '!diff -U0 ' .. v:fname_in .. ' ' .. v:fname_new .. '>>' .. v:fname_out 993 endfunc 994 func SetupUnified() 995 set diffexpr=UnifiedDiffExpr() 996 diffupdate 997 endfunc 998 func StopUnified() 999 set diffexpr= 1000 endfunc 1001 END 1002 call writefile(lines, 'XdiffSetup', 'D') 1003 1004 " clean up already existing swap files, just in case 1005 call delete('.Xdifile1.swp') 1006 call delete('.Xdifile2.swp') 1007 1008 " Test 1: Add a line in beginning of file 2 1009 call WriteDiffFiles(0, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) 1010 let buf = RunVimInTerminal('-d -S XdiffSetup Xdifile1 Xdifile2', {}) 1011 " Set autoread mode, so that Vim won't complain once we re-write the test 1012 " files 1013 call term_sendkeys(buf, ":set autoread\<CR>\<c-w>w:set autoread\<CR>\<c-w>w") 1014 1015 call VerifyBoth(buf, 'Test_diff_01', '') 1016 1017 " Test 2: Add a line in beginning of file 1 1018 call WriteDiffFiles(buf, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) 1019 call VerifyBoth(buf, 'Test_diff_02', '') 1020 1021 " Test 3: Add a line at the end of file 2 1022 call WriteDiffFiles(buf, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]) 1023 call VerifyBoth(buf, 'Test_diff_03', '') 1024 1025 " Test 4: Add a line at the end of file 1 1026 call WriteDiffFiles(buf, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) 1027 call VerifyBoth(buf, 'Test_diff_04', '') 1028 1029 " Test 5: Add a line in the middle of file 2, remove on at the end of file 1 1030 call WriteDiffFiles(buf, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], [1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10]) 1031 call VerifyBoth(buf, 'Test_diff_05', '') 1032 1033 " Test 6: Add a line in the middle of file 1, remove on at the end of file 2 1034 call WriteDiffFiles(buf, [1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]) 1035 call VerifyBoth(buf, 'Test_diff_06', '') 1036 1037 " Variants on test 6 with different context settings 1038 call term_sendkeys(buf, ":set diffopt+=context:2\<cr>") 1039 call VerifyScreenDump(buf, 'Test_diff_06.2', {}) 1040 call term_sendkeys(buf, ":set diffopt-=context:2\<cr>") 1041 call term_sendkeys(buf, ":set diffopt+=context:1\<cr>") 1042 call VerifyScreenDump(buf, 'Test_diff_06.1', {}) 1043 call term_sendkeys(buf, ":set diffopt-=context:1\<cr>") 1044 call term_sendkeys(buf, ":set diffopt+=context:0\<cr>") 1045 call VerifyScreenDump(buf, 'Test_diff_06.0', {}) 1046 call term_sendkeys(buf, ":set diffopt-=context:0\<cr>") 1047 1048 " Test 7 - 9: Test normal/patience/histogram diff algorithm 1049 call WriteDiffFiles(buf, ['#include <stdio.h>', '', '// Frobs foo heartily', 'int frobnitz(int foo)', '{', 1050 \ ' int i;', ' for(i = 0; i < 10; i++)', ' {', ' printf("Your answer is: ");', 1051 \ ' printf("%d\n", foo);', ' }', '}', '', 'int fact(int n)', '{', ' if(n > 1)', ' {', 1052 \ ' return fact(n-1) * n;', ' }', ' return 1;', '}', '', 'int main(int argc, char **argv)', 1053 \ '{', ' frobnitz(fact(10));', '}'], 1054 \ ['#include <stdio.h>', '', 'int fib(int n)', '{', ' if(n > 2)', ' {', 1055 \ ' return fib(n-1) + fib(n-2);', ' }', ' return 1;', '}', '', '// Frobs foo heartily', 1056 \ 'int frobnitz(int foo)', '{', ' int i;', ' for(i = 0; i < 10; i++)', ' {', 1057 \ ' printf("%d\n", foo);', ' }', '}', '', 1058 \ 'int main(int argc, char **argv)', '{', ' frobnitz(fib(10));', '}']) 1059 call term_sendkeys(buf, ":diffupdate!\<cr>") 1060 call term_sendkeys(buf, ":set diffopt+=internal\<cr>") 1061 call VerifyScreenDump(buf, 'Test_diff_07', {}) 1062 1063 call term_sendkeys(buf, ":set diffopt+=algorithm:patience\<cr>") 1064 call VerifyScreenDump(buf, 'Test_diff_08', {}) 1065 1066 call term_sendkeys(buf, ":set diffopt+=algorithm:histogram\<cr>") 1067 call VerifyScreenDump(buf, 'Test_diff_09', {}) 1068 1069 " Test 10-11: with/without indent-heuristic 1070 call term_sendkeys(buf, ":set diffopt&vim\<cr>") 1071 call WriteDiffFiles(buf, ['', ' def finalize(values)', '', ' values.each do |v|', ' v.finalize', ' end'], 1072 \ ['', ' def finalize(values)', '', ' values.each do |v|', ' v.prepare', ' end', '', 1073 \ ' values.each do |v|', ' v.finalize', ' end']) 1074 call term_sendkeys(buf, ":diffupdate!\<cr>") 1075 call term_sendkeys(buf, ":set diffopt+=internal\<cr>:\<cr>") 1076 call VerifyScreenDump(buf, 'Test_diff_11', {}) 1077 1078 " Leave trailing : at commandline! 1079 call term_sendkeys(buf, ":set diffopt-=indent-heuristic\<cr>:\<cr>") 1080 call VerifyScreenDump(buf, 'Test_diff_10', {}, 'one') 1081 " shouldn't matter, if indent-algorithm comes before or after the algorithm 1082 call term_sendkeys(buf, ":set diffopt&\<cr>") 1083 call term_sendkeys(buf, ":set diffopt+=indent-heuristic,algorithm:patience\<cr>:\<cr>") 1084 call VerifyScreenDump(buf, 'Test_diff_11', {}, 'two') 1085 call term_sendkeys(buf, ":set diffopt&\<cr>") 1086 call term_sendkeys(buf, ":set diffopt+=algorithm:patience,indent-heuristic\<cr>:\<cr>") 1087 call VerifyScreenDump(buf, 'Test_diff_11', {}, 'three') 1088 1089 " Test 12: diff the same file 1090 call WriteDiffFiles(buf, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) 1091 call VerifyBoth(buf, 'Test_diff_12', '') 1092 1093 " Test 13: diff an empty file 1094 call WriteDiffFiles(buf, [], []) 1095 call VerifyBoth(buf, 'Test_diff_13', '') 1096 1097 " Test 14: test diffopt+=icase 1098 call WriteDiffFiles(buf, ['a', 'b', 'cd'], ['A', 'b', 'cDe']) 1099 call VerifyBoth(buf, 'Test_diff_14', " diffopt+=filler diffopt+=icase") 1100 1101 " Test 15-16: test diffopt+=iwhite 1102 call WriteDiffFiles(buf, ['int main()', '{', ' printf("Hello, World!");', ' return 0;', '}'], 1103 \ ['int main()', '{', ' if (0)', ' {', ' printf("Hello, World!");', ' return 0;', ' }', '}']) 1104 call term_sendkeys(buf, ":diffupdate!\<cr>") 1105 call term_sendkeys(buf, ":set diffopt&vim diffopt+=filler diffopt+=iwhite\<cr>") 1106 call VerifyScreenDump(buf, 'Test_diff_15', {}) 1107 call term_sendkeys(buf, ":set diffopt+=internal\<cr>") 1108 call VerifyScreenDump(buf, 'Test_diff_16', {}) 1109 1110 " Test 17: test diffopt+=iblank 1111 call WriteDiffFiles(buf, ['a', ' ', 'cd', 'ef', 'xxx'], ['a', 'cd', '', 'ef', 'yyy']) 1112 call VerifyInternal(buf, 'Test_diff_17', " diffopt+=iblank") 1113 1114 " Test 18: test diffopt+=iblank,iwhite / iwhiteall / iwhiteeol 1115 call VerifyInternal(buf, 'Test_diff_18', " diffopt+=iblank,iwhite") 1116 call VerifyInternal(buf, 'Test_diff_18', " diffopt+=iblank,iwhiteall") 1117 call VerifyInternal(buf, 'Test_diff_18', " diffopt+=iblank,iwhiteeol") 1118 1119 " Test 19: test diffopt+=iwhiteeol 1120 call WriteDiffFiles(buf, ['a ', 'x', 'cd', 'ef', 'xx xx', 'foo', 'bar'], ['a', 'x', 'c d', ' ef', 'xx xx', 'foo', '', 'bar']) 1121 call VerifyInternal(buf, 'Test_diff_19', " diffopt+=iwhiteeol") 1122 1123 " Test 20: test diffopt+=iwhiteall 1124 call VerifyInternal(buf, 'Test_diff_20', " diffopt+=iwhiteall") 1125 1126 " Test 21: Delete all lines 1127 call WriteDiffFiles(buf, [0], []) 1128 call VerifyBoth(buf, "Test_diff_21", "") 1129 1130 " Test 22: Add line to empty file 1131 call WriteDiffFiles(buf, [], [0]) 1132 call VerifyBoth(buf, "Test_diff_22", "") 1133 1134 call WriteDiffFiles(buf, ['?a', '?b', '?c'], ['!b']) 1135 call VerifyInternal(buf, 'Test_diff_23', " diffopt+=linematch:30") 1136 1137 call WriteDiffFiles(buf, ['', 1138 \ 'common line', 1139 \ 'common line', 1140 \ '', 1141 \ 'DEFabc', 1142 \ 'xyz', 1143 \ 'xyz', 1144 \ 'xyz', 1145 \ 'DEFabc', 1146 \ 'DEFabc', 1147 \ 'DEFabc', 1148 \ 'common line', 1149 \ 'common line', 1150 \ 'DEF', 1151 \ 'common line', 1152 \ 'DEF', 1153 \ 'something' ], 1154 \ ['', 1155 \ 'common line', 1156 \ 'common line', 1157 \ '', 1158 \ 'ABCabc', 1159 \ 'ABCabc', 1160 \ 'ABCabc', 1161 \ 'ABCabc', 1162 \ 'common line', 1163 \ 'common line', 1164 \ 'common line', 1165 \ 'something']) 1166 call VerifyInternal(buf, 'Test_diff_24', " diffopt+=linematch:30") 1167 1168 1169 " clean up 1170 call StopVimInTerminal(buf) 1171 call delete('Xdifile1') 1172 call delete('Xdifile2') 1173 endfunc 1174 1175 func Test_diff_with_scroll_and_change() 1176 CheckScreendump 1177 1178 let lines =<< trim END 1179 call setline(1, range(1, 15)) 1180 vnew 1181 call setline(1, range(9, 15)) 1182 windo diffthis 1183 wincmd h 1184 exe "normal Gl5\<C-E>" 1185 END 1186 call writefile(lines, 'Xtest_scroll_change', 'D') 1187 let buf = RunVimInTerminal('-S Xtest_scroll_change', {}) 1188 1189 call VerifyScreenDump(buf, 'Test_diff_scroll_change_01', {}) 1190 1191 call term_sendkeys(buf, "ax\<Esc>") 1192 call VerifyScreenDump(buf, 'Test_diff_scroll_change_02', {}) 1193 1194 call term_sendkeys(buf, "\<C-W>lay\<Esc>") 1195 call VerifyScreenDump(buf, 'Test_diff_scroll_change_03', {}) 1196 1197 " clean up 1198 call StopVimInTerminal(buf) 1199 endfunc 1200 1201 func Test_diff_with_cursorline() 1202 CheckScreendump 1203 1204 call writefile([ 1205 \ 'hi CursorLine ctermbg=red ctermfg=white', 1206 \ 'set cursorline', 1207 \ 'call setline(1, ["foo","foo","foo","bar"])', 1208 \ 'vnew', 1209 \ 'call setline(1, ["bee","foo","foo","baz"])', 1210 \ 'windo diffthis', 1211 \ '2wincmd w', 1212 \ ], 'Xtest_diff_cursorline', 'D') 1213 let buf = RunVimInTerminal('-S Xtest_diff_cursorline', {}) 1214 1215 call VerifyScreenDump(buf, 'Test_diff_with_cursorline_01', {}) 1216 call term_sendkeys(buf, "j") 1217 call VerifyScreenDump(buf, 'Test_diff_with_cursorline_02', {}) 1218 call term_sendkeys(buf, "j") 1219 call VerifyScreenDump(buf, 'Test_diff_with_cursorline_03', {}) 1220 1221 " clean up 1222 call StopVimInTerminal(buf) 1223 endfunc 1224 1225 func Test_diff_with_cursorline_number() 1226 CheckScreendump 1227 1228 let lines =<< trim END 1229 hi CursorLine ctermbg=red ctermfg=white 1230 hi CursorLineNr ctermbg=white ctermfg=black cterm=underline 1231 set cursorline number 1232 call setline(1, ["baz", "foo", "foo", "bar"]) 1233 2 1234 vnew 1235 call setline(1, ["foo", "foo", "bar"]) 1236 windo diffthis 1237 1wincmd w 1238 END 1239 call writefile(lines, 'Xtest_diff_cursorline_number', 'D') 1240 let buf = RunVimInTerminal('-S Xtest_diff_cursorline_number', {}) 1241 1242 call VerifyScreenDump(buf, 'Test_diff_with_cursorline_number_01', {}) 1243 call term_sendkeys(buf, ":set cursorlineopt=number\r") 1244 call VerifyScreenDump(buf, 'Test_diff_with_cursorline_number_02', {}) 1245 1246 " clean up 1247 call StopVimInTerminal(buf) 1248 endfunc 1249 1250 func Test_diff_with_cursorline_breakindent() 1251 CheckScreendump 1252 1253 let lines =<< trim END 1254 hi CursorLine ctermbg=red ctermfg=white 1255 set noequalalways wrap diffopt=followwrap cursorline breakindent 1256 50vnew 1257 call setline(1, [' ', ' ', ' ', ' ']) 1258 exe "norm! 20Afoo\<Esc>j20Afoo\<Esc>j20Afoo\<Esc>j20Abar\<Esc>" 1259 vnew 1260 call setline(1, [' ', ' ', ' ', ' ']) 1261 exe "norm! 20Abee\<Esc>j20Afoo\<Esc>j20Afoo\<Esc>j20Abaz\<Esc>" 1262 windo diffthis 1263 2wincmd w 1264 END 1265 call writefile(lines, 'Xtest_diff_cursorline_breakindent', 'D') 1266 let buf = RunVimInTerminal('-S Xtest_diff_cursorline_breakindent', {}) 1267 1268 call term_sendkeys(buf, "gg0") 1269 call VerifyScreenDump(buf, 'Test_diff_with_cul_bri_01', {}) 1270 call term_sendkeys(buf, "j") 1271 call VerifyScreenDump(buf, 'Test_diff_with_cul_bri_02', {}) 1272 call term_sendkeys(buf, "j") 1273 call VerifyScreenDump(buf, 'Test_diff_with_cul_bri_03', {}) 1274 call term_sendkeys(buf, "j") 1275 call VerifyScreenDump(buf, 'Test_diff_with_cul_bri_04', {}) 1276 1277 " clean up 1278 call StopVimInTerminal(buf) 1279 endfunc 1280 1281 func Test_diff_breakindent_after_filler() 1282 CheckScreendump 1283 1284 let lines =<< trim END 1285 set laststatus=0 diffopt+=followwrap breakindent breakindentopt=min:0 1286 call setline(1, ['a', ' ' .. repeat('c', 50)]) 1287 vnew 1288 call setline(1, ['a', 'b', ' ' .. repeat('c', 50)]) 1289 windo diffthis 1290 norm! G$ 1291 END 1292 call writefile(lines, 'Xtest_diff_breakindent_after_filler', 'D') 1293 let buf = RunVimInTerminal('-S Xtest_diff_breakindent_after_filler', #{rows: 8, cols: 45}) 1294 call VerifyScreenDump(buf, 'Test_diff_breakindent_after_filler', {}) 1295 1296 " clean up 1297 call StopVimInTerminal(buf) 1298 endfunc 1299 1300 func Test_diff_with_syntax() 1301 CheckScreendump 1302 1303 let lines =<< trim END 1304 void doNothing() { 1305 int x = 0; 1306 char *s = "hello"; 1307 return 5; 1308 } 1309 END 1310 call writefile(lines, 'Xprogram1.c', 'D') 1311 let lines =<< trim END 1312 void doSomething() { 1313 int x = 0; 1314 char *s = "there"; 1315 return 5; 1316 } 1317 END 1318 call writefile(lines, 'Xprogram2.c', 'D') 1319 1320 let lines =<< trim END 1321 set diffopt=internal,filler 1322 edit Xprogram1.c 1323 diffsplit Xprogram2.c 1324 END 1325 call writefile(lines, 'Xtest_diff_syntax', 'D') 1326 let buf = RunVimInTerminal('-S Xtest_diff_syntax', {}) 1327 1328 call VerifyScreenDump(buf, 'Test_diff_syntax_1', {}) 1329 1330 " clean up 1331 call StopVimInTerminal(buf) 1332 endfunc 1333 1334 func Test_diff_of_diff() 1335 CheckScreendump 1336 CheckFeature rightleft 1337 1338 call writefile([ 1339 \ 'call setline(1, ["aa","bb","cc","@@ -3,2 +5,7 @@","dd","ee","ff"])', 1340 \ 'vnew', 1341 \ 'call setline(1, ["aa","bb","cc"])', 1342 \ 'windo diffthis', 1343 \ '1wincmd w', 1344 \ 'setlocal number', 1345 \ ], 'Xtest_diff_diff', 'D') 1346 let buf = RunVimInTerminal('-S Xtest_diff_diff', {}) 1347 1348 call VerifyScreenDump(buf, 'Test_diff_of_diff_01', {}) 1349 1350 call term_sendkeys(buf, ":set rightleft\<cr>") 1351 call VerifyScreenDump(buf, 'Test_diff_of_diff_02', {}) 1352 1353 " clean up 1354 call StopVimInTerminal(buf) 1355 endfunc 1356 1357 func CloseoffSetup() 1358 enew 1359 call setline(1, ['one', 'two', 'three']) 1360 diffthis 1361 new 1362 call setline(1, ['one', 'tow', 'three']) 1363 diffthis 1364 call assert_equal(1, &diff) 1365 bw! 1366 endfunc 1367 1368 func Test_diff_closeoff() 1369 " "closeoff" included by default: last diff win gets 'diff' reset' 1370 call CloseoffSetup() 1371 call assert_equal(0, &diff) 1372 enew! 1373 1374 " "closeoff" excluded: last diff win keeps 'diff' set' 1375 set diffopt-=closeoff 1376 call CloseoffSetup() 1377 call assert_equal(1, &diff) 1378 diffoff! 1379 enew! 1380 endfunc 1381 1382 func Test_diff_followwrap() 1383 new 1384 set diffopt+=followwrap 1385 set wrap 1386 diffthis 1387 call assert_equal(1, &wrap) 1388 diffoff 1389 set nowrap 1390 diffthis 1391 call assert_equal(0, &wrap) 1392 diffoff 1393 set diffopt& 1394 bwipe! 1395 endfunc 1396 1397 func Test_diff_maintains_change_mark() 1398 func DiffMaintainsChangeMark() 1399 enew! 1400 call setline(1, ['a', 'b', 'c', 'd']) 1401 diffthis 1402 new 1403 call setline(1, ['a', 'b', 'c', 'e']) 1404 " Set '[ and '] marks 1405 2,3yank 1406 call assert_equal([2, 3], [line("'["), line("']")]) 1407 " Verify they aren't affected by the implicit diff 1408 diffthis 1409 call assert_equal([2, 3], [line("'["), line("']")]) 1410 " Verify they aren't affected by an explicit diff 1411 diffupdate 1412 call assert_equal([2, 3], [line("'["), line("']")]) 1413 bwipe! 1414 bwipe! 1415 endfunc 1416 1417 set diffopt-=internal 1418 call DiffMaintainsChangeMark() 1419 set diffopt+=internal 1420 call DiffMaintainsChangeMark() 1421 1422 set diffopt& 1423 delfunc DiffMaintainsChangeMark 1424 endfunc 1425 1426 " Test for 'patchexpr' 1427 func Test_patchexpr() 1428 let g:patch_args = [] 1429 func TPatch() 1430 call add(g:patch_args, readfile(v:fname_in)) 1431 call add(g:patch_args, readfile(v:fname_diff)) 1432 call writefile(['output file'], v:fname_out) 1433 endfunc 1434 set patchexpr=TPatch() 1435 1436 call writefile(['input file'], 'Xinput', 'D') 1437 call writefile(['diff file'], 'Xdiff', 'D') 1438 %bwipe! 1439 edit Xinput 1440 diffpatch Xdiff 1441 call assert_equal('output file', getline(1)) 1442 call assert_equal('Xinput.new', bufname()) 1443 call assert_equal(2, winnr('$')) 1444 call assert_true(&diff) 1445 1446 " Using a script-local function 1447 func s:NewPatchExpr() 1448 endfunc 1449 set patchexpr=s:NewPatchExpr() 1450 call assert_equal(expand('<SID>') .. 'NewPatchExpr()', &patchexpr) 1451 set patchexpr=<SID>NewPatchExpr() 1452 call assert_equal(expand('<SID>') .. 'NewPatchExpr()', &patchexpr) 1453 1454 set patchexpr& 1455 delfunc TPatch 1456 delfunc s:NewPatchExpr 1457 %bwipe! 1458 endfunc 1459 1460 func Test_diff_rnu() 1461 CheckScreendump 1462 1463 let content =<< trim END 1464 set diffopt=internal,filler 1465 call setline(1, ['a', 'a', 'a', 'y', 'b', 'b', 'b', 'b', 'b']) 1466 vnew 1467 call setline(1, ['a', 'a', 'a', 'x', 'x', 'x', 'b', 'b', 'b', 'b', 'b']) 1468 windo diffthis 1469 setlocal number rnu foldcolumn=0 1470 END 1471 call writefile(content, 'Xtest_diff_rnu', 'D') 1472 let buf = RunVimInTerminal('-S Xtest_diff_rnu', {}) 1473 1474 call VerifyScreenDump(buf, 'Test_diff_rnu_01', {}) 1475 1476 call term_sendkeys(buf, "j") 1477 call VerifyScreenDump(buf, 'Test_diff_rnu_02', {}) 1478 call term_sendkeys(buf, "j") 1479 call VerifyScreenDump(buf, 'Test_diff_rnu_03', {}) 1480 1481 " clean up 1482 call StopVimInTerminal(buf) 1483 endfunc 1484 1485 func Test_diff_multilineconceal() 1486 new 1487 diffthis 1488 1489 new 1490 call matchadd('Conceal', 'a\nb', 9, -1, {'conceal': 'Y'}) 1491 set cole=2 cocu=n 1492 call setline(1, ["a", "b"]) 1493 diffthis 1494 redraw 1495 endfunc 1496 1497 func Test_diff_and_scroll() 1498 " this was causing an ml_get error 1499 set ls=2 1500 for i in range(winheight(0) * 2) 1501 call setline(i, i < winheight(0) - 10 ? i : i + 10) 1502 endfor 1503 vnew 1504 for i in range(winheight(0)*2 + 10) 1505 call setline(i, i < winheight(0) - 10 ? 0 : i) 1506 endfor 1507 diffthis 1508 wincmd p 1509 diffthis 1510 execute 'normal ' . winheight(0) . "\<C-d>" 1511 1512 bwipe! 1513 bwipe! 1514 set ls& 1515 endfunc 1516 1517 func Test_diff_filler_cursorcolumn() 1518 CheckScreendump 1519 1520 let content =<< trim END 1521 call setline(1, ['aa', 'bb', 'cc']) 1522 vnew 1523 call setline(1, ['aa', 'cc']) 1524 windo diffthis 1525 wincmd p 1526 setlocal cursorcolumn foldcolumn=0 1527 norm! gg0 1528 redraw! 1529 END 1530 call writefile(content, 'Xtest_diff_cuc', 'D') 1531 let buf = RunVimInTerminal('-S Xtest_diff_cuc', {}) 1532 1533 call VerifyScreenDump(buf, 'Test_diff_cuc_01', {}) 1534 1535 call term_sendkeys(buf, "l") 1536 call term_sendkeys(buf, "\<C-l>") 1537 call VerifyScreenDump(buf, 'Test_diff_cuc_02', {}) 1538 call term_sendkeys(buf, "0j") 1539 call term_sendkeys(buf, "\<C-l>") 1540 call VerifyScreenDump(buf, 'Test_diff_cuc_03', {}) 1541 call term_sendkeys(buf, "l") 1542 call term_sendkeys(buf, "\<C-l>") 1543 call VerifyScreenDump(buf, 'Test_diff_cuc_04', {}) 1544 1545 " clean up 1546 call StopVimInTerminal(buf) 1547 endfunc 1548 1549 " Test for adding/removing lines inside diff chunks, between diff chunks 1550 " and before diff chunks 1551 func Test_diff_modify_chunks() 1552 set diffopt=internal,filler 1553 enew! 1554 let w2_id = win_getid() 1555 call setline(1, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']) 1556 new 1557 let w1_id = win_getid() 1558 call setline(1, ['a', '2', '3', 'd', 'e', 'f', '7', '8', 'i']) 1559 windo diffthis 1560 1561 " remove a line between two diff chunks and create a new diff chunk 1562 call win_gotoid(w2_id) 1563 5d 1564 call win_gotoid(w1_id) 1565 call diff_hlID(5, 1)->synIDattr('name')->assert_equal('DiffAdd') 1566 1567 " add a line between two diff chunks 1568 call win_gotoid(w2_id) 1569 normal! 4Goe 1570 call win_gotoid(w1_id) 1571 call diff_hlID(4, 1)->synIDattr('name')->assert_equal('') 1572 call diff_hlID(5, 1)->synIDattr('name')->assert_equal('') 1573 1574 " remove all the lines in a diff chunk. 1575 call win_gotoid(w2_id) 1576 7,8d 1577 call win_gotoid(w1_id) 1578 let hl = range(1, 9)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')}) 1579 call assert_equal(['', 'DiffText', 'DiffText', '', '', '', 'DiffAdd', 1580 \ 'DiffAdd', ''], hl) 1581 1582 " remove lines from one diff chunk to just before the next diff chunk 1583 call win_gotoid(w2_id) 1584 call setline(1, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']) 1585 2,6d 1586 call win_gotoid(w1_id) 1587 let hl = range(1, 9)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')}) 1588 call assert_equal(['', 'DiffText', 'DiffText', 'DiffAdd', 'DiffAdd', 1589 \ 'DiffAdd', 'DiffAdd', 'DiffAdd', ''], hl) 1590 1591 " remove lines just before the top of a diff chunk 1592 call win_gotoid(w2_id) 1593 call setline(1, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']) 1594 5,6d 1595 call win_gotoid(w1_id) 1596 let hl = range(1, 9)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')}) 1597 call assert_equal(['', 'DiffText', 'DiffText', '', 'DiffText', 'DiffText', 1598 \ 'DiffAdd', 'DiffAdd', ''], hl) 1599 1600 " remove line after the end of a diff chunk 1601 call win_gotoid(w2_id) 1602 call setline(1, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']) 1603 4d 1604 call win_gotoid(w1_id) 1605 let hl = range(1, 9)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')}) 1606 call assert_equal(['', 'DiffText', 'DiffText', 'DiffAdd', '', '', 'DiffText', 1607 \ 'DiffText', ''], hl) 1608 1609 " remove lines starting from the end of one diff chunk and ending inside 1610 " another diff chunk 1611 call win_gotoid(w2_id) 1612 call setline(1, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']) 1613 4,7d 1614 call win_gotoid(w1_id) 1615 let hl = range(1, 9)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')}) 1616 call assert_equal(['', 'DiffText', 'DiffText', 'DiffText', 'DiffAdd', 1617 \ 'DiffAdd', 'DiffAdd', 'DiffAdd', ''], hl) 1618 1619 " removing the only remaining diff chunk should make the files equal 1620 call win_gotoid(w2_id) 1621 call setline(1, ['a', '2', '3', 'x', 'd', 'e', 'f', 'x', '7', '8', 'i']) 1622 8d 1623 let hl = range(1, 10)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')}) 1624 call assert_equal(['', '', '', 'DiffAdd', '', '', '', '', '', ''], hl) 1625 call win_gotoid(w2_id) 1626 4d 1627 call win_gotoid(w1_id) 1628 let hl = range(1, 9)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')}) 1629 call assert_equal(['', '', '', '', '', '', '', '', ''], hl) 1630 1631 %bw! 1632 set diffopt& 1633 endfunc 1634 1635 func Test_diff_binary() 1636 CheckScreendump 1637 1638 let content =<< trim END 1639 call setline(1, ['a', 'b', "c\n", 'd', 'e', 'f', 'g']) 1640 vnew 1641 call setline(1, ['A', 'b', 'c', 'd', 'E', 'f', 'g']) 1642 windo diffthis 1643 wincmd p 1644 norm! gg0 1645 redraw! 1646 END 1647 call writefile(content, 'Xtest_diff_bin', 'D') 1648 let buf = RunVimInTerminal('-S Xtest_diff_bin', {}) 1649 1650 " Test using internal diff 1651 call VerifyScreenDump(buf, 'Test_diff_bin_01', {}) 1652 1653 " Test using internal diff and case folding 1654 call term_sendkeys(buf, ":set diffopt+=icase\<cr>") 1655 call term_sendkeys(buf, "\<C-l>") 1656 call VerifyScreenDump(buf, 'Test_diff_bin_02', {}) 1657 " Test using external diff 1658 call term_sendkeys(buf, ":set diffopt=filler\<cr>") 1659 call term_sendkeys(buf, "\<C-l>") 1660 call VerifyScreenDump(buf, 'Test_diff_bin_03', {}) 1661 " Test using external diff and case folding 1662 call term_sendkeys(buf, ":set diffopt=filler,icase\<cr>") 1663 call term_sendkeys(buf, "\<C-l>") 1664 call VerifyScreenDump(buf, 'Test_diff_bin_04', {}) 1665 1666 " clean up 1667 call StopVimInTerminal(buf) 1668 set diffopt&vim 1669 endfunc 1670 1671 " Test for using the 'zi' command to invert 'foldenable' in diff windows (test 1672 " for the issue fixed by patch 6.2.317) 1673 func Test_diff_foldinvert() 1674 %bw! 1675 edit Xdoffile1 1676 new Xdoffile2 1677 new Xdoffile3 1678 windo diffthis 1679 " open a non-diff window 1680 botright new 1681 1wincmd w 1682 call assert_true(getwinvar(1, '&foldenable')) 1683 call assert_true(getwinvar(2, '&foldenable')) 1684 call assert_true(getwinvar(3, '&foldenable')) 1685 normal zi 1686 call assert_false(getwinvar(1, '&foldenable')) 1687 call assert_false(getwinvar(2, '&foldenable')) 1688 call assert_false(getwinvar(3, '&foldenable')) 1689 normal zi 1690 call assert_true(getwinvar(1, '&foldenable')) 1691 call assert_true(getwinvar(2, '&foldenable')) 1692 call assert_true(getwinvar(3, '&foldenable')) 1693 1694 " If the current window has 'noscrollbind', then 'zi' should not change 1695 " 'foldenable' in other windows. 1696 1wincmd w 1697 set noscrollbind 1698 normal zi 1699 call assert_false(getwinvar(1, '&foldenable')) 1700 call assert_true(getwinvar(2, '&foldenable')) 1701 call assert_true(getwinvar(3, '&foldenable')) 1702 1703 " 'zi' should not change the 'foldenable' for windows with 'noscrollbind' 1704 1wincmd w 1705 set scrollbind 1706 normal zi 1707 call setwinvar(2, '&scrollbind', v:false) 1708 normal zi 1709 call assert_false(getwinvar(1, '&foldenable')) 1710 call assert_true(getwinvar(2, '&foldenable')) 1711 call assert_false(getwinvar(3, '&foldenable')) 1712 1713 %bw! 1714 set scrollbind& 1715 endfunc 1716 1717 " This was scrolling for 'cursorbind' but 'scrollbind' is more important 1718 func Test_diff_scroll() 1719 CheckScreendump 1720 1721 let left =<< trim END 1722 line 1 1723 line 2 1724 line 3 1725 line 4 1726 1727 // Common block 1728 // one 1729 // containing 1730 // four lines 1731 1732 // Common block 1733 // two 1734 // containing 1735 // four lines 1736 END 1737 call writefile(left, 'Xleft', 'D') 1738 let right =<< trim END 1739 line 1 1740 line 2 1741 line 3 1742 line 4 1743 1744 Lorem 1745 ipsum 1746 dolor 1747 sit 1748 amet, 1749 consectetur 1750 adipiscing 1751 elit. 1752 Etiam 1753 luctus 1754 lectus 1755 sodales, 1756 dictum 1757 1758 // Common block 1759 // one 1760 // containing 1761 // four lines 1762 1763 Vestibulum 1764 tincidunt 1765 aliquet 1766 nulla. 1767 1768 // Common block 1769 // two 1770 // containing 1771 // four lines 1772 END 1773 call writefile(right, 'Xright', 'D') 1774 let buf = RunVimInTerminal('-d Xleft Xright', {'rows': 12}) 1775 call term_sendkeys(buf, "\<C-W>\<C-W>jjjj") 1776 call VerifyScreenDump(buf, 'Test_diff_scroll_1', {}) 1777 call term_sendkeys(buf, "j") 1778 call VerifyScreenDump(buf, 'Test_diff_scroll_2', {}) 1779 1780 call StopVimInTerminal(buf) 1781 endfunc 1782 1783 " This was scrolling too many lines. 1784 func Test_diff_scroll_wrap_on() 1785 20new 1786 40vsplit 1787 call setline(1, map(range(1, 9), 'repeat(v:val, 200)')) 1788 setlocal number diff so=0 1789 redraw 1790 normal! jj 1791 call assert_equal(1, winsaveview().topline) 1792 normal! j 1793 call assert_equal(2, winsaveview().topline) 1794 1795 bwipe! 1796 bwipe! 1797 endfunc 1798 1799 func Test_diff_scroll_many_filler() 1800 20new 1801 vnew 1802 call setline(1, range(1, 40)) 1803 diffthis 1804 setlocal scrolloff=0 1805 wincmd p 1806 call setline(1, range(1, 20)->reverse() + ['###']->repeat(41) + range(21, 40)->reverse()) 1807 diffthis 1808 setlocal scrolloff=0 1809 wincmd p 1810 redraw 1811 1812 " Note: need a redraw after each scroll, otherwise the test always passes. 1813 for _ in range(2) 1814 normal! G 1815 redraw 1816 call assert_equal(40, winsaveview().topline) 1817 call assert_equal(19, winsaveview().topfill) 1818 exe "normal! \<C-B>" 1819 redraw 1820 call assert_equal(22, winsaveview().topline) 1821 call assert_equal(0, winsaveview().topfill) 1822 exe "normal! \<C-B>" 1823 redraw 1824 call assert_equal(4, winsaveview().topline) 1825 call assert_equal(0, winsaveview().topfill) 1826 exe "normal! \<C-B>" 1827 redraw 1828 call assert_equal(1, winsaveview().topline) 1829 call assert_equal(0, winsaveview().topfill) 1830 set smoothscroll 1831 endfor 1832 1833 set smoothscroll& 1834 %bwipe! 1835 endfunc 1836 1837 " This was trying to update diffs for a buffer being closed 1838 func Test_diff_only() 1839 silent! lfile 1840 set diff 1841 lopen 1842 norm o 1843 silent! norm o 1844 1845 set nodiff 1846 %bwipe! 1847 endfunc 1848 1849 " This was causing invalid diff block values 1850 " FIXME: somehow this causes a valgrind error when run directly but not when 1851 " run as a test. 1852 func Test_diff_manipulations() 1853 set diff 1854 split 0 1855 sil! norm RdoobdeuRdoobdeuRdoobdeu 1856 1857 set nodiff 1858 %bwipe! 1859 endfunc 1860 1861 " This was causing the line number in the diff block to go below one. 1862 " FIXME: somehow this causes a valgrind error when run directly but not when 1863 " run as a test. 1864 func Test_diff_put_and_undo() 1865 set diff 1866 next 0 1867 split 00 1868 sil! norm o0gguudpo0ggJuudp 1869 1870 bwipe! 1871 bwipe! 1872 set nodiff 1873 endfunc 1874 1875 1876 func Test_diff_toggle_wrap_skipcol_leftcol() 1877 61vnew 1878 call setline(1, 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.') 1879 30vnew 1880 call setline(1, 'ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.') 1881 let win1 = win_getid() 1882 setlocal smoothscroll 1883 exe "normal! $\<C-E>" 1884 wincmd l 1885 let win2 = win_getid() 1886 setlocal smoothscroll 1887 exe "normal! $\<C-E>" 1888 call assert_equal([ 1889 \ '<<<sadipscing elitr, sed diam |<<<tetur sadipscing elitr, sed|', 1890 \ 'nonumy eirmod tempor invidunt | diam nonumy eirmod tempor inv|', 1891 \ 'ut labore et dolore magna aliq|idunt ut labore et dolore magn|', 1892 \ 'uyam erat, sed diam voluptua. |a aliquyam erat, sed diam volu|', 1893 \ '~ |ptua. |', 1894 \ ], ScreenLines([1, 5], 62)) 1895 call assert_equal({'col': 29, 'row': 4, 'endcol': 29, 'curscol': 29}, 1896 \ screenpos(win1, line('.', win1), col('.', win1))) 1897 call assert_equal({'col': 36, 'row': 5, 'endcol': 36, 'curscol': 36}, 1898 \ screenpos(win2, line('.', win2), col('.', win2))) 1899 1900 wincmd h 1901 diffthis 1902 wincmd l 1903 diffthis 1904 normal! 0 1905 call assert_equal([ 1906 \ ' ipsum dolor sit amet, conset| Lorem ipsum dolor sit amet, |', 1907 \ '~ |~ |', 1908 \ ], ScreenLines([1, 2], 62)) 1909 call assert_equal({'col': 3, 'row': 1, 'endcol': 3, 'curscol': 3}, 1910 \ screenpos(win1, line('.', win1), col('.', win1))) 1911 call assert_equal({'col': 34, 'row': 1, 'endcol': 34, 'curscol': 34}, 1912 \ screenpos(win2, line('.', win2), col('.', win2))) 1913 1914 normal! $ 1915 call assert_equal([ 1916 \ ' voluptua. | diam voluptua. |', 1917 \ '~ |~ |', 1918 \ ], ScreenLines([1, 2], 62)) 1919 call assert_equal({'col': 11, 'row': 1, 'endcol': 11, 'curscol': 11}, 1920 \ screenpos(win1, line('.', win1), col('.', win1))) 1921 call assert_equal({'col': 48, 'row': 1, 'endcol': 48, 'curscol': 48}, 1922 \ screenpos(win2, line('.', win2), col('.', win2))) 1923 1924 diffoff! 1925 call assert_equal([ 1926 \ 'ipsum dolor sit amet, consetet|Lorem ipsum dolor sit amet, co|', 1927 \ 'ur sadipscing elitr, sed diam |nsetetur sadipscing elitr, sed|', 1928 \ 'nonumy eirmod tempor invidunt | diam nonumy eirmod tempor inv|', 1929 \ 'ut labore et dolore magna aliq|idunt ut labore et dolore magn|', 1930 \ 'uyam erat, sed diam voluptua. |a aliquyam erat, sed diam volu|', 1931 \ '~ |ptua. |', 1932 \ ], ScreenLines([1, 6], 62)) 1933 call assert_equal({'col': 29, 'row': 5, 'endcol': 29, 'curscol': 29}, 1934 \ screenpos(win1, line('.', win1), col('.', win1))) 1935 call assert_equal({'col': 36, 'row': 6, 'endcol': 36, 'curscol': 36}, 1936 \ screenpos(win2, line('.', win2), col('.', win2))) 1937 1938 bwipe! 1939 bwipe! 1940 endfunc 1941 1942 " Ctrl-D reveals filler lines below the last line in the buffer. 1943 func Test_diff_eob_halfpage() 1944 new 1945 call setline(1, ['']->repeat(10) + ['a']) 1946 diffthis 1947 new 1948 call setline(1, ['']->repeat(3) + ['a', 'b']) 1949 diffthis 1950 resize 5 1951 wincmd j 1952 resize 5 1953 norm G 1954 call assert_equal(7, line('w0')) 1955 exe "norm! \<C-D>" 1956 call assert_equal(8, line('w0')) 1957 1958 %bwipe! 1959 endfunc 1960 1961 func Test_diff_overlapped_diff_blocks_will_be_merged() 1962 CheckScreendump 1963 1964 let lines =<< trim END 1965 func DiffExprStub() 1966 let txt_in = readfile(v:fname_in) 1967 let txt_new = readfile(v:fname_new) 1968 if txt_in == ["line1"] && txt_new == ["line2"] 1969 call writefile(["1c1"], v:fname_out) 1970 elseif txt_in == readfile("Xdiin1") && txt_new == readfile("Xdinew1") 1971 call writefile(readfile("Xdiout1"), v:fname_out) 1972 elseif txt_in == readfile("Xdiin2") && txt_new == readfile("Xdinew2") 1973 call writefile(readfile("Xdiout2"), v:fname_out) 1974 endif 1975 endfunc 1976 END 1977 call writefile(lines, 'XdiffSetup', 'D') 1978 1979 call WriteDiffFiles(0, [], []) 1980 let buf = RunVimInTerminal('-d -S XdiffSetup Xdifile1 Xdifile2', {}) 1981 call term_sendkeys(buf, ":set autoread\<CR>\<c-w>w:set autoread\<CR>\<c-w>w") 1982 1983 call WriteDiffFiles(buf, ["a", "b"], ["x", "x"]) 1984 call writefile(["a", "b"], "Xdiin1") 1985 call writefile(["x", "x"], "Xdinew1") 1986 call writefile(["1c1", "2c2"], "Xdiout1") 1987 call term_sendkeys(buf, ":set diffexpr=DiffExprStub()\<CR>:") 1988 call VerifyBoth(buf, "Test_diff_overlapped_2.01", "") 1989 call term_sendkeys(buf, ":set diffexpr&\<CR>:") 1990 1991 call WriteDiffFiles(buf, ["a", "b", "c"], ["x", "c"]) 1992 call writefile(["a", "b", "c"], "Xdiin1") 1993 call writefile(["x", "c"], "Xdinew1") 1994 call writefile(["1c1", "2d1"], "Xdiout1") 1995 call term_sendkeys(buf, ":set diffexpr=DiffExprStub()\<CR>:") 1996 call VerifyBoth(buf, "Test_diff_overlapped_2.02", "") 1997 call term_sendkeys(buf, ":set diffexpr&\<CR>:") 1998 1999 call WriteDiffFiles(buf, ["a", "c"], ["x", "x", "c"]) 2000 call writefile(["a", "c"], "Xdiin1") 2001 call writefile(["x", "x", "c"], "Xdinew1") 2002 call writefile(["1c1", "1a2"], "Xdiout1") 2003 call term_sendkeys(buf, ":set diffexpr=DiffExprStub()\<CR>:") 2004 call VerifyBoth(buf, "Test_diff_overlapped_2.03", "") 2005 call term_sendkeys(buf, ":set diffexpr&\<CR>:") 2006 2007 call StopVimInTerminal(buf) 2008 wincmd c 2009 2010 call WriteDiffFiles3(0, [], [], []) 2011 let buf = RunVimInTerminal('-d -S XdiffSetup Xdifile1 Xdifile2 Xdifile3', {}) 2012 call term_sendkeys(buf, ":set autoread\<CR>\<c-w>w:set autoread\<CR>\<c-w>w:set autoread\<CR>\<c-w>w") 2013 2014 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["y", "b", "c"]) 2015 call VerifyBoth(buf, "Test_diff_overlapped_3.01", "") 2016 2017 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["a", "y", "c"]) 2018 call VerifyBoth(buf, "Test_diff_overlapped_3.02", "") 2019 2020 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["a", "b", "y"]) 2021 call VerifyBoth(buf, "Test_diff_overlapped_3.03", "") 2022 2023 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["y", "y", "c"]) 2024 call VerifyBoth(buf, "Test_diff_overlapped_3.04", "") 2025 2026 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["a", "y", "y"]) 2027 call VerifyBoth(buf, "Test_diff_overlapped_3.05", "") 2028 2029 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["y", "y", "y"]) 2030 call VerifyBoth(buf, "Test_diff_overlapped_3.06", "") 2031 2032 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "x"], ["y", "y", "c"]) 2033 call VerifyBoth(buf, "Test_diff_overlapped_3.07", "") 2034 2035 call WriteDiffFiles3(buf, ["a", "b", "c"], ["x", "x", "c"], ["a", "y", "y"]) 2036 call VerifyBoth(buf, "Test_diff_overlapped_3.08", "") 2037 2038 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["y", "y", "y", "d", "e"]) 2039 call VerifyBoth(buf, "Test_diff_overlapped_3.09", "") 2040 2041 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["y", "y", "y", "y", "e"]) 2042 call VerifyBoth(buf, "Test_diff_overlapped_3.10", "") 2043 2044 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["y", "y", "y", "y", "y"]) 2045 call VerifyBoth(buf, "Test_diff_overlapped_3.11", "") 2046 2047 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "y", "y", "d", "e"]) 2048 call VerifyBoth(buf, "Test_diff_overlapped_3.12", "") 2049 2050 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "y", "y", "y", "e"]) 2051 call VerifyBoth(buf, "Test_diff_overlapped_3.13", "") 2052 2053 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "y", "y", "y", "y"]) 2054 call VerifyBoth(buf, "Test_diff_overlapped_3.14", "") 2055 2056 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "b", "y", "d", "e"]) 2057 call VerifyBoth(buf, "Test_diff_overlapped_3.15", "") 2058 2059 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "b", "y", "y", "e"]) 2060 call VerifyBoth(buf, "Test_diff_overlapped_3.16", "") 2061 2062 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "b", "y", "y", "y"]) 2063 call VerifyBoth(buf, "Test_diff_overlapped_3.17", "") 2064 2065 call WriteDiffFiles3(buf, ["a", "b"], ["x", "b"], ["y", "y"]) 2066 call writefile(["a", "b"], "Xdiin1") 2067 call writefile(["x", "b"], "Xdinew1") 2068 call writefile(["1c1"], "Xdiout1") 2069 call writefile(["a", "b"], "Xdiin2") 2070 call writefile(["y", "y"], "Xdinew2") 2071 call writefile(["1c1", "2c2"], "Xdiout2") 2072 call term_sendkeys(buf, ":set diffexpr=DiffExprStub()\<CR>:") 2073 call VerifyInternal(buf, "Test_diff_overlapped_3.18", "") 2074 call term_sendkeys(buf, ":set diffexpr&\<CR>:") 2075 2076 call WriteDiffFiles3(buf, ["a", "b", "c", "d"], ["x", "b", "x", "d"], ["y", "y", "c", "d"]) 2077 call writefile(["a", "b", "c", "d"], "Xdiin1") 2078 call writefile(["x", "b", "x", "d"], "Xdinew1") 2079 call writefile(["1c1", "3c3"], "Xdiout1") 2080 call writefile(["a", "b", "c", "d"], "Xdiin2") 2081 call writefile(["y", "y", "c", "d"], "Xdinew2") 2082 call writefile(["1c1", "2c2"], "Xdiout2") 2083 call term_sendkeys(buf, ":set diffexpr=DiffExprStub()\<CR>:") 2084 call VerifyInternal(buf, "Test_diff_overlapped_3.19", "") 2085 call term_sendkeys(buf, ":set diffexpr&\<CR>:") 2086 2087 call WriteDiffFiles3(buf, ["a", "b", "c", "d"], ["x", "b", "x", "d"], ["y", "y", "y", "d"]) 2088 call writefile(["a", "b", "c", "d"], "Xdiin1") 2089 call writefile(["x", "b", "x", "d"], "Xdinew1") 2090 call writefile(["1c1", "3c3"], "Xdiout1") 2091 call writefile(["a", "b", "c", "d"], "Xdiin2") 2092 call writefile(["y", "y", "y", "d"], "Xdinew2") 2093 call writefile(["1c1", "2,3c2,3"], "Xdiout2") 2094 call term_sendkeys(buf, ":set diffexpr=DiffExprStub()\<CR>:") 2095 call VerifyInternal(buf, "Test_diff_overlapped_3.20", "") 2096 call term_sendkeys(buf, ":set diffexpr&\<CR>:") 2097 2098 call WriteDiffFiles3(buf, ["a", "b", "c", "d"], ["x", "b", "x", "d"], ["y", "y", "y", "y"]) 2099 call writefile(["a", "b", "c", "d"], "Xdiin1") 2100 call writefile(["x", "b", "x", "d"], "Xdinew1") 2101 call writefile(["1c1", "3c3"], "Xdiout1") 2102 call writefile(["a", "b", "c", "d"], "Xdiin2") 2103 call writefile(["y", "y", "y", "y"], "Xdinew2") 2104 call writefile(["1c1", "2,4c2,4"], "Xdiout2") 2105 call term_sendkeys(buf, ":set diffexpr=DiffExprStub()\<CR>:") 2106 call VerifyInternal(buf, "Test_diff_overlapped_3.21", "") 2107 call term_sendkeys(buf, ":set diffexpr&\<CR>:") 2108 2109 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["b", "c"]) 2110 call VerifyBoth(buf, "Test_diff_overlapped_3.22", "") 2111 2112 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["c"]) 2113 call VerifyBoth(buf, "Test_diff_overlapped_3.23", "") 2114 2115 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], []) 2116 call VerifyBoth(buf, "Test_diff_overlapped_3.24", "") 2117 2118 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["a", "c"]) 2119 call VerifyBoth(buf, "Test_diff_overlapped_3.25", "") 2120 2121 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["a"]) 2122 call VerifyBoth(buf, "Test_diff_overlapped_3.26", "") 2123 2124 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["b"]) 2125 call VerifyBoth(buf, "Test_diff_overlapped_3.27", "") 2126 2127 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["d", "e"]) 2128 call VerifyBoth(buf, "Test_diff_overlapped_3.28", "") 2129 2130 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["e"]) 2131 call VerifyBoth(buf, "Test_diff_overlapped_3.29", "") 2132 2133 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "d", "e"]) 2134 call VerifyBoth(buf, "Test_diff_overlapped_3.30", "") 2135 2136 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "e"]) 2137 call VerifyBoth(buf, "Test_diff_overlapped_3.31", "") 2138 2139 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a"]) 2140 call VerifyBoth(buf, "Test_diff_overlapped_3.32", "") 2141 2142 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "b", "d", "e"]) 2143 call VerifyBoth(buf, "Test_diff_overlapped_3.33", "") 2144 2145 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "b", "e"]) 2146 call VerifyBoth(buf, "Test_diff_overlapped_3.34", "") 2147 2148 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "b"]) 2149 call VerifyBoth(buf, "Test_diff_overlapped_3.35", "") 2150 2151 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["a", "y", "b", "c"]) 2152 call VerifyBoth(buf, "Test_diff_overlapped_3.36", "") 2153 2154 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["a", "b", "y", "c"]) 2155 call VerifyBoth(buf, "Test_diff_overlapped_3.37", "") 2156 2157 call WriteDiffFiles3(buf, ["a", "b", "c"], ["d", "e"], ["b", "f"]) 2158 call VerifyBoth(buf, "Test_diff_overlapped_3.38", "") 2159 2160 call WriteDiffFiles3(buf, ["a", "b", "c"], ["d", "e"], ["b"]) 2161 call VerifyBoth(buf, "Test_diff_overlapped_3.39", "") 2162 2163 " File 3 overlaps twice, 2nd overlap completely within the existing block. 2164 call WriteDiffFiles3(buf, ["foo", "a", "b", "c", "bar"], ["foo", "w", "x", "y", "z", "bar"], ["foo", "1", "a", "b", "2", "bar"]) 2165 call VerifyBoth(buf, "Test_diff_overlapped_3.40", "") 2166 2167 " File 3 overlaps twice, 2nd overlap extends beyond existing block on new 2168 " side. Make sure we don't over-extend the range and hit 'bar'. 2169 call WriteDiffFiles3(buf, ["foo", "a", "b", "c", "d", "bar"], ["foo", "w", "x", "y", "z", "u", "bar"], ["foo", "1", "a", "b", "2", "d", "bar"]) 2170 call VerifyBoth(buf, "Test_diff_overlapped_3.41", "") 2171 2172 " Chained overlaps. File 3's 2nd overlap spans two diff blocks and is longer 2173 " than the 2nd one. 2174 call WriteDiffFiles3(buf, ["foo", "a", "b", "c", "d", "e", "f", "bar"], ["foo", "w", "x", "y", "z", "e", "u", "bar"], ["foo", "1", "b", "2", "3", "d", "4", "f", "bar"]) 2175 call VerifyBoth(buf, "Test_diff_overlapped_3.42", "") 2176 2177 " File 3 has 2 overlaps. An add and a delete. First overlap's expansion hits 2178 " the 2nd one. Make sure we adjust the diff block to have fewer lines. 2179 call WriteDiffFiles3(buf, ["foo", "a", "b", "bar"], ["foo", "x", "y", "bar"], ["foo", "1", "a", "bar"]) 2180 call VerifyBoth(buf, "Test_diff_overlapped_3.43", "") 2181 2182 " File 3 has 2 overlaps. An add and another add. First overlap's expansion hits 2183 " the 2nd one. Make sure we adjust the diff block to have more lines. 2184 call WriteDiffFiles3(buf, ["foo", "a", "b", "c", "d", "bar"], ["foo", "w", "x", "y", "z", "u", "bar"], ["foo", "1", "a", "b", "3", "4", "d", "bar"]) 2185 call VerifyBoth(buf, "Test_diff_overlapped_3.44", "") 2186 2187 call StopVimInTerminal(buf) 2188 endfunc 2189 2190 " switching windows in diff mode caused an unnecessary scroll 2191 func Test_diff_topline_noscroll() 2192 CheckScreendump 2193 2194 let content =<< trim END 2195 call setline(1, range(1,60)) 2196 vnew 2197 call setline(1, range(1,10) + range(50,60)) 2198 windo diffthis 2199 norm! G 2200 exe "norm! 30\<C-y>" 2201 END 2202 call writefile(content, 'Xcontent', 'D') 2203 let buf = RunVimInTerminal('-S Xcontent', {'rows': 20}) 2204 call VerifyScreenDump(buf, 'Test_diff_topline_1', {}) 2205 call term_sendkeys(buf, ":echo line('w0', 1001)\<cr>") 2206 call term_wait(buf) 2207 call VerifyScreenDump(buf, 'Test_diff_topline_2', {}) 2208 call term_sendkeys(buf, "\<C-W>p") 2209 call term_wait(buf) 2210 call VerifyScreenDump(buf, 'Test_diff_topline_3', {}) 2211 call term_sendkeys(buf, "\<C-W>p") 2212 call term_wait(buf) 2213 call VerifyScreenDump(buf, 'Test_diff_topline_4', {}) 2214 call StopVimInTerminal(buf) 2215 endfunc 2216 2217 " Test inline highlighting which shows what's different within each diff block 2218 func Test_diff_inline() 2219 CheckScreendump 2220 2221 call WriteDiffFiles(0, [], []) 2222 let buf = RunVimInTerminal('-d Xdifile1 Xdifile2', {}) 2223 call term_sendkeys(buf, ":set autoread\<CR>\<c-w>w:set autoread\<CR>\<c-w>w") 2224 2225 call WriteDiffFiles(buf, ["abcdef ghi jk n", "x", "y"], ["aBcef gHi lm n", "y", "z"]) 2226 call VerifyInternal(buf, "Test_diff_inline_01", "") 2227 call VerifyInternal(buf, "Test_diff_inline_02", " diffopt+=inline:none") 2228 2229 " inline:simple is the same as default 2230 call VerifyInternal(buf, "Test_diff_inline_01", " diffopt+=inline:simple") 2231 2232 call VerifyInternal(buf, "Test_diff_inline_03", " diffopt+=inline:char") 2233 call VerifyInternal(buf, "Test_diff_inline_04", " diffopt+=inline:word") 2234 2235 " multiple inline values will the last one 2236 call VerifyInternal(buf, "Test_diff_inline_01", " diffopt+=inline:none,inline:char,inline:simple") 2237 call VerifyInternal(buf, "Test_diff_inline_02", " diffopt+=inline:simple,inline:word,inline:none") 2238 call VerifyInternal(buf, "Test_diff_inline_03", " diffopt+=inline:simple,inline:word,inline:char") 2239 2240 " DiffTextAdd highlight 2241 call term_sendkeys(buf, ":hi DiffTextAdd ctermbg=blue\<CR>") 2242 call VerifyInternal(buf, "Test_diff_inline_05", " diffopt+=inline:char") 2243 2244 " Live update in insert mode 2245 call term_sendkeys(buf, "\<Esc>isometext") 2246 call VerifyScreenDump(buf, "Test_diff_inline_06", {}) 2247 call term_sendkeys(buf, "\<Esc>u") 2248 2249 " icase simple scenarios 2250 call VerifyInternal(buf, "Test_diff_inline_07", " diffopt+=inline:simple,icase") 2251 call VerifyInternal(buf, "Test_diff_inline_08", " diffopt+=inline:char,icase") 2252 call VerifyInternal(buf, "Test_diff_inline_09", " diffopt+=inline:word,icase") 2253 2254 " diff algorithms should affect highlight 2255 call WriteDiffFiles(buf, ["apples and oranges"], ["oranges and apples"]) 2256 call VerifyInternal(buf, "Test_diff_inline_10", " diffopt+=inline:char") 2257 call VerifyInternal(buf, "Test_diff_inline_11", " diffopt+=inline:char,algorithm:patience") 2258 2259 " icase: composing chars and Unicode fold case edge cases 2260 call WriteDiffFiles(buf, 2261 \ ["1 - sigma in 6σ and Ὀδυσσεύς", "1 - angstrom in åå", "1 - composing: ii⃗I⃗"], 2262 \ ["2 - Sigma in 6Σ and ὈΔΥΣΣΕΎΣ", "2 - Angstrom in ÅÅ", "2 - Composing: i⃗I⃗I⃗"]) 2263 call VerifyInternal(buf, "Test_diff_inline_12", " diffopt+=inline:char") 2264 call VerifyInternal(buf, "Test_diff_inline_13", " diffopt+=inline:char,icase") 2265 2266 " wide chars 2267 call WriteDiffFiles(buf, ["abc😅xde一", "f🚀g"], ["abcy😢de", "二f🚀g"]) 2268 call VerifyInternal(buf, "Test_diff_inline_14", " diffopt+=inline:char,icase") 2269 2270 " NUL char (\n below is internally substituted as NUL) 2271 call WriteDiffFiles(buf, ["1\n34\n5\n6"], ["1234\n5", "6"]) 2272 call VerifyInternal(buf, "Test_diff_inline_15", " diffopt+=inline:char") 2273 2274 " word diff: always use first buffer's iskeyword and ignore others' for consistency 2275 call WriteDiffFiles(buf, ["foo+bar test"], ["foo+baz test"]) 2276 call VerifyInternal(buf, "Test_diff_inline_word_01", " diffopt+=inline:word") 2277 2278 call term_sendkeys(buf, ":set iskeyword+=+\<CR>:diffupdate\<CR>") 2279 call VerifyInternal(buf, "Test_diff_inline_word_02", " diffopt+=inline:word") 2280 2281 call term_sendkeys(buf, ":set iskeyword&\<CR>:wincmd w\<CR>") 2282 call term_sendkeys(buf, ":set iskeyword+=+\<CR>:wincmd w\<CR>:diffupdate\<CR>") 2283 " Use the previous screen dump as 2nd buffer's iskeyword does not matter 2284 call VerifyInternal(buf, "Test_diff_inline_word_01", " diffopt+=inline:word") 2285 2286 call term_sendkeys(buf, ":windo set iskeyword&\<CR>:1wincmd w\<CR>") 2287 2288 " word diff: test handling of multi-byte characters. Only alphanumeric chars 2289 " (e.g. Greek alphabet, but not CJK/emoji) count as words. 2290 call WriteDiffFiles(buf, ["🚀⛵️一二三ひらがなΔέλτα Δelta foobar"], ["🚀🛸一二四ひらなδέλτα δelta foobar"]) 2291 call VerifyInternal(buf, "Test_diff_inline_word_03", " diffopt+=inline:word") 2292 2293 " char diff: should slide highlight to whitespace boundary if possible for 2294 " better readability (by using forced indent-heuristics). A wrong result 2295 " would be if the highlight is "Bar, prefix". It should be "prefixBar, " 2296 " instead. 2297 call WriteDiffFiles(buf, ["prefixFoo, prefixEnd"], ["prefixFoo, prefixBar, prefixEnd"]) 2298 call VerifyInternal(buf, "Test_diff_inline_char_01", " diffopt+=inline:char") 2299 2300 " char diff: small gaps between inline diff blocks will be merged during refine step 2301 " - first segment: test that we iteratively merge small gaps after we merged 2302 " adjacent blocks, but only with limited number (set to 4) of iterations. 2303 " - second and third segments: show that we need a large enough adjacent block to 2304 " trigger a merge. 2305 " - fourth segment: small gaps are not merged when adjacent large block is 2306 " on a different line. 2307 call WriteDiffFiles(buf, 2308 \ ["abcdefghijklmno", "anchor1", 2309 \ "abcdefghijklmno", "anchor2", 2310 \ "abcdefghijklmno", "anchor3", 2311 \ "test", "multiline"], 2312 \ ["a?c?e?g?i?k???o", "anchor1", 2313 \ "a??de?????klmno", "anchor2", 2314 \ "a??de??????lmno", "anchor3", 2315 \ "t?s?", "??????i?e"]) 2316 call VerifyInternal(buf, "Test_diff_inline_char_02", " diffopt+=inline:char") 2317 2318 " Test multi-line blocks and whitespace 2319 call WriteDiffFiles(buf, 2320 \ ["this is ", "sometest text foo", "baz abc def ", "one", "word another word", "additional line"], 2321 \ ["this is some test", "texts", "foo bar abX Yef ", "oneword another word"]) 2322 call VerifyInternal(buf, "Test_diff_inline_multiline_01", " diffopt+=inline:char,iwhite") 2323 call VerifyInternal(buf, "Test_diff_inline_multiline_02", " diffopt+=inline:word,iwhite") 2324 call VerifyInternal(buf, "Test_diff_inline_multiline_03", " diffopt+=inline:char,iwhiteeol") 2325 call VerifyInternal(buf, "Test_diff_inline_multiline_04", " diffopt+=inline:word,iwhiteeol") 2326 call VerifyInternal(buf, "Test_diff_inline_multiline_05", " diffopt+=inline:char,iwhiteall") 2327 call VerifyInternal(buf, "Test_diff_inline_multiline_06", " diffopt+=inline:word,iwhiteall") 2328 2329 " newline should be highlighted too when 'list' is set 2330 call term_sendkeys(buf, ":windo set list\<CR>") 2331 call VerifyInternal(buf, "Test_diff_inline_multiline_07", " diffopt+=inline:char") 2332 call VerifyInternal(buf, "Test_diff_inline_multiline_08", " diffopt+=inline:char,iwhite") 2333 call VerifyInternal(buf, "Test_diff_inline_multiline_09", " diffopt+=inline:char,iwhiteeol") 2334 call VerifyInternal(buf, "Test_diff_inline_multiline_10", " diffopt+=inline:char,iwhiteall") 2335 call term_sendkeys(buf, ":windo set nolist\<CR>") 2336 2337 call StopVimInTerminal(buf) 2338 endfunc 2339 2340 func Test_diff_inline_multibuffer() 2341 CheckScreendump 2342 2343 call WriteDiffFiles3(0, [], [], []) 2344 let buf = RunVimInTerminal('-d Xdifile1 Xdifile2 Xdifile3', {}) 2345 call term_sendkeys(buf, ":windo set autoread\<CR>:1wincmd w\<CR>") 2346 call term_sendkeys(buf, ":hi DiffTextAdd ctermbg=blue\<CR>") 2347 2348 call WriteDiffFiles3(buf, 2349 \ ["That is buffer1.", "anchor", "Some random text", "anchor"], 2350 \ ["This is buffer2.", "anchor", "Some text", "anchor", "buffer2/3"], 2351 \ ["This is buffer3. Last.", "anchor", "Some more", "text here.", "anchor", "only in buffer2/3", "not in buffer1"]) 2352 call VerifyInternal(buf, "Test_diff_inline_multibuffer_01", " diffopt+=inline:char") 2353 2354 " Close one of the buffers and make sure it updates correctly 2355 call term_sendkeys(buf, ":diffoff\<CR>") 2356 call VerifyInternal(buf, "Test_diff_inline_multibuffer_02", " diffopt+=inline:char") 2357 2358 " Update text in the non-diff buffer and nothing should be changed 2359 call term_sendkeys(buf, "\<Esc>isometext") 2360 call VerifyScreenDump(buf, "Test_diff_inline_multibuffer_03", {}) 2361 call term_sendkeys(buf, "\<Esc>u") 2362 2363 call term_sendkeys(buf, ":diffthis\<CR>") 2364 call VerifyInternal(buf, "Test_diff_inline_multibuffer_01", " diffopt+=inline:char") 2365 2366 " Test that removing first buffer from diff will in turn use the next 2367 " earliest buffer's iskeyword during word diff. 2368 call WriteDiffFiles3(buf, 2369 \ ["This+is=a-setence"], 2370 \ ["This+is=another-setence"], 2371 \ ["That+is=a-setence"]) 2372 call term_sendkeys(buf, ":set iskeyword+=+\<CR>:2wincmd w\<CR>:set iskeyword+=-\<CR>:1wincmd w\<CR>") 2373 call VerifyInternal(buf, "Test_diff_inline_multibuffer_04", " diffopt+=inline:word") 2374 call term_sendkeys(buf, ":diffoff\<CR>") 2375 call VerifyInternal(buf, "Test_diff_inline_multibuffer_05", " diffopt+=inline:word") 2376 call term_sendkeys(buf, ":diffthis\<CR>") 2377 call VerifyInternal(buf, "Test_diff_inline_multibuffer_04", " diffopt+=inline:word") 2378 2379 " Test multi-buffer char diff refinement, and that removing a buffer from 2380 " diff will update the others properly. 2381 call WriteDiffFiles3(buf, 2382 \ ["abcdefghijkYmYYY"], 2383 \ ["aXXdXXghijklmnop"], 2384 \ ["abcdefghijkYmYop"]) 2385 call VerifyInternal(buf, "Test_diff_inline_multibuffer_06", " diffopt+=inline:char") 2386 call term_sendkeys(buf, ":diffoff\<CR>") 2387 call VerifyInternal(buf, "Test_diff_inline_multibuffer_07", " diffopt+=inline:char") 2388 call term_sendkeys(buf, ":diffthis\<CR>") 2389 call VerifyInternal(buf, "Test_diff_inline_multibuffer_06", " diffopt+=inline:char") 2390 2391 call StopVimInTerminal(buf) 2392 endfunc 2393 2394 " Test that when using multi-buffer diff, an empty block would be correctly 2395 " skipped in the result, without resulting in invalid states or crashes. 2396 func Test_diff_inline_multibuffer_empty_block() 2397 CheckScreendump 2398 2399 call writefile(['anchor1', '1234567890abcde', 'anchor2'], 'Xdifile1') 2400 call writefile(['anchor1', '1234567--0abc-e', 'anchor2'], 'Xdifile2') 2401 call writefile(['anchor1', 'anchor2'], 'Xdifile3') 2402 call writefile(['anchor1', '1???????90abcd?', 'anchor2'], 'Xdifile4') 2403 2404 let buf = RunVimInTerminal('-d Xdifile1 Xdifile2 Xdifile3 Xdifile4', {}) 2405 call VerifyInternal(buf, "Test_diff_inline_multibuffer_empty_block_01", " diffopt+=inline:char") 2406 2407 call StopVimInTerminal(buf) 2408 endfunc 2409 2410 func Test_diffget_diffput_linematch() 2411 CheckScreendump 2412 call delete('.Xdifile1.swp') 2413 call delete('.Xdifile2.swp') 2414 call WriteDiffFiles(0, [], []) 2415 let buf = RunVimInTerminal('-d Xdifile1 Xdifile2', {}) 2416 call term_sendkeys(buf, ":set autoread\<CR>\<c-w>w:set autoread\<CR>\<c-w>w") 2417 2418 " enable linematch 2419 call term_sendkeys(buf, ":set diffopt+=linematch:30\<CR>") 2420 call WriteDiffFiles(buf, ['', 2421 \ 'common line', 2422 \ 'common line', 2423 \ '', 2424 \ 'ABCabc', 2425 \ 'ABCabc', 2426 \ 'ABCabc', 2427 \ 'ABCabc', 2428 \ 'common line', 2429 \ 'common line', 2430 \ 'common line', 2431 \ 'something' ], 2432 \ ['', 2433 \ 'common line', 2434 \ 'common line', 2435 \ '', 2436 \ 'DEFabc', 2437 \ 'xyz', 2438 \ 'xyz', 2439 \ 'xyz', 2440 \ 'DEFabc', 2441 \ 'DEFabc', 2442 \ 'DEFabc', 2443 \ 'common line', 2444 \ 'common line', 2445 \ 'DEF', 2446 \ 'common line', 2447 \ 'DEF', 2448 \ 'something']) 2449 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_1', {}) 2450 2451 " get from window 1 from line 5 to 9 2452 call term_sendkeys(buf, "1\<c-w>w") 2453 call term_sendkeys(buf, ":5,9diffget\<CR>") 2454 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_2', {}) 2455 2456 " undo the last diffget 2457 call term_sendkeys(buf, "u") 2458 2459 " get from window 2 from line 5 to 10 2460 call term_sendkeys(buf, "2\<c-w>w") 2461 call term_sendkeys(buf, ":5,10diffget\<CR>") 2462 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_3', {}) 2463 2464 " undo the last diffget 2465 call term_sendkeys(buf, "u") 2466 2467 " get all from window 2 2468 call term_sendkeys(buf, "2\<c-w>w") 2469 call term_sendkeys(buf, ":4,17diffget\<CR>") 2470 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_4', {}) 2471 2472 " undo the last diffget 2473 call term_sendkeys(buf, "u") 2474 2475 " get all from window 1 2476 call term_sendkeys(buf, "1\<c-w>w") 2477 call term_sendkeys(buf, ":4,12diffget\<CR>") 2478 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_5', {}) 2479 2480 " undo the last diffget 2481 call term_sendkeys(buf, "u") 2482 2483 " get from window 1 using do 1 line 5 2484 call term_sendkeys(buf, "1\<c-w>w") 2485 call term_sendkeys(buf, "5gg") 2486 call term_sendkeys(buf, ":diffget\<CR>") 2487 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_6', {}) 2488 2489 " undo the last diffget 2490 call term_sendkeys(buf, "u") 2491 2492 " get from window 1 using do 2 line 6 2493 call term_sendkeys(buf, "1\<c-w>w") 2494 call term_sendkeys(buf, "6gg") 2495 call term_sendkeys(buf, ":diffget\<CR>") 2496 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_7', {}) 2497 2498 " undo the last diffget 2499 call term_sendkeys(buf, "u") 2500 2501 " get from window 1 using do 2 line 7 2502 call term_sendkeys(buf, "1\<c-w>w") 2503 call term_sendkeys(buf, "7gg") 2504 call term_sendkeys(buf, ":diffget\<CR>") 2505 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_8', {}) 2506 2507 " undo the last diffget 2508 call term_sendkeys(buf, "u") 2509 2510 " get from window 1 using do 2 line 11 2511 call term_sendkeys(buf, "1\<c-w>w") 2512 call term_sendkeys(buf, "11gg") 2513 call term_sendkeys(buf, ":diffget\<CR>") 2514 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_9', {}) 2515 2516 " undo the last diffget 2517 call term_sendkeys(buf, "u") 2518 2519 " get from window 1 using do 2 line 12 2520 call term_sendkeys(buf, "1\<c-w>w") 2521 call term_sendkeys(buf, "12gg") 2522 call term_sendkeys(buf, ":diffget\<CR>") 2523 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_10', {}) 2524 2525 " undo the last diffget 2526 call term_sendkeys(buf, "u") 2527 2528 " put from window 1 using dp 1 line 5 2529 call term_sendkeys(buf, "1\<c-w>w") 2530 call term_sendkeys(buf, "5gg") 2531 call term_sendkeys(buf, ":diffput\<CR>") 2532 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_11', {}) 2533 2534 " undo the last diffput 2535 call term_sendkeys(buf, "2\<c-w>w") 2536 call term_sendkeys(buf, "u") 2537 2538 " put from window 1 using dp 2 line 6 2539 call term_sendkeys(buf, "1\<c-w>w") 2540 call term_sendkeys(buf, "6gg") 2541 call term_sendkeys(buf, ":diffput\<CR>") 2542 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_12', {}) 2543 2544 " undo the last diffput 2545 call term_sendkeys(buf, "2\<c-w>w") 2546 call term_sendkeys(buf, "u") 2547 2548 " put from window 1 using dp 2 line 7 2549 call term_sendkeys(buf, "1\<c-w>w") 2550 call term_sendkeys(buf, "7gg") 2551 call term_sendkeys(buf, ":diffput\<CR>") 2552 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_13', {}) 2553 2554 " undo the last diffput 2555 call term_sendkeys(buf, "2\<c-w>w") 2556 call term_sendkeys(buf, "u") 2557 2558 " put from window 1 using dp 2 line 11 2559 call term_sendkeys(buf, "1\<c-w>w") 2560 call term_sendkeys(buf, "11gg") 2561 call term_sendkeys(buf, ":diffput\<CR>") 2562 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_14', {}) 2563 2564 " undo the last diffput 2565 call term_sendkeys(buf, "2\<c-w>w") 2566 call term_sendkeys(buf, "u") 2567 2568 " put from window 1 using dp 2 line 12 2569 call term_sendkeys(buf, "1\<c-w>w") 2570 call term_sendkeys(buf, "12gg") 2571 call term_sendkeys(buf, ":diffput\<CR>") 2572 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_15', {}) 2573 2574 " undo the last diffput 2575 call term_sendkeys(buf, "2\<c-w>w") 2576 call term_sendkeys(buf, "u") 2577 2578 " put from window 2 using dp line 6 2579 call term_sendkeys(buf, "2\<c-w>w") 2580 call term_sendkeys(buf, "6gg") 2581 call term_sendkeys(buf, ":diffput\<CR>") 2582 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_16', {}) 2583 2584 " undo the last diffput 2585 call term_sendkeys(buf, "1\<c-w>w") 2586 call term_sendkeys(buf, "u") 2587 2588 " put from window 2 using dp line 8 2589 call term_sendkeys(buf, "2\<c-w>w") 2590 call term_sendkeys(buf, "8gg") 2591 call term_sendkeys(buf, ":diffput\<CR>") 2592 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_17', {}) 2593 2594 " undo the last diffput 2595 call term_sendkeys(buf, "1\<c-w>w") 2596 call term_sendkeys(buf, "u") 2597 2598 " put from window 2 using dp line 9 2599 call term_sendkeys(buf, "2\<c-w>w") 2600 call term_sendkeys(buf, "9gg") 2601 call term_sendkeys(buf, ":diffput\<CR>") 2602 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_18', {}) 2603 2604 " undo the last diffput 2605 call term_sendkeys(buf, "1\<c-w>w") 2606 call term_sendkeys(buf, "u") 2607 2608 " put from window 2 using dp line 17 2609 call term_sendkeys(buf, "2\<c-w>w") 2610 call term_sendkeys(buf, "17gg") 2611 call term_sendkeys(buf, ":diffput\<CR>") 2612 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_19', {}) 2613 " clean up 2614 call StopVimInTerminal(buf) 2615 endfunc 2616 2617 func Test_linematch_diff() 2618 CheckScreendump 2619 call delete('.Xdifile1.swp') 2620 call delete('.Xdifile2.swp') 2621 call WriteDiffFiles(0, [], []) 2622 let buf = RunVimInTerminal('-d Xdifile1 Xdifile2', {}) 2623 call term_sendkeys(buf, ":set autoread\<CR>\<c-w>w:set autoread\<CR>\<c-w>w") 2624 2625 " enable linematch 2626 call term_sendkeys(buf, ":set diffopt=internal,filler,linematch:30\<CR>") 2627 call WriteDiffFiles(buf, ['// abc d?', 2628 \ '// d?', 2629 \ '// d?' ], 2630 \ ['!', 2631 \ 'abc d!', 2632 \ 'd!']) 2633 call term_sendkeys(buf, ":\<CR>") " clear cmdline 2634 call VerifyScreenDump(buf, 'Test_linematch_diff1', {}) 2635 2636 " test that filler is always implicitly set by linematch 2637 call term_sendkeys(buf, ":set diffopt-=filler\<CR>") 2638 call term_sendkeys(buf, ":\<CR>") " clear cmdline 2639 call VerifyScreenDump(buf, 'Test_linematch_diff1', {}) 2640 2641 " clean up 2642 call StopVimInTerminal(buf) 2643 endfunc 2644 2645 func Test_linematch_diff_iwhite() 2646 CheckScreendump 2647 call delete('.Xdifile1.swp') 2648 call delete('.Xdifile2.swp') 2649 call WriteDiffFiles(0, [], []) 2650 let buf = RunVimInTerminal('-d Xdifile1 Xdifile2', {}) 2651 call term_sendkeys(buf, ":set autoread\<CR>\<c-w>w:set autoread\<CR>\<c-w>w") 2652 2653 " setup a diff with 2 files and set linematch:30, with ignore white 2654 call term_sendkeys(buf, ":set diffopt=internal,filler,linematch:30\<CR>") 2655 call WriteDiffFiles(buf, ['void testFunction () {', 2656 \ ' for (int i = 0; i < 10; i++) {', 2657 \ ' for (int j = 0; j < 10; j++) {', 2658 \ ' }', 2659 \ ' }', 2660 \ '}' ], 2661 \ ['void testFunction () {', 2662 \ ' // for (int j = 0; j < 10; i++) {', 2663 \ ' // }', 2664 \ '}']) 2665 call VerifyScreenDump(buf, 'Test_linematch_diff_iwhite1', {}) 2666 call term_sendkeys(buf, ":set diffopt+=iwhiteall\<CR>") 2667 call VerifyScreenDump(buf, 'Test_linematch_diff_iwhite2', {}) 2668 " clean up 2669 call StopVimInTerminal(buf) 2670 endfunc 2671 2672 func Test_linematch_diff_grouping() 2673 CheckScreendump 2674 call delete('.Xdifile1.swp') 2675 call delete('.Xdifile2.swp') 2676 call WriteDiffFiles(0, [], []) 2677 let buf = RunVimInTerminal('-d Xdifile1 Xdifile2', {}) 2678 call term_sendkeys(buf, ":set autoread\<CR>\<c-w>w:set autoread\<CR>\<c-w>w") 2679 2680 " a diff that would result in multiple groups before grouping optimization 2681 call term_sendkeys(buf, ":set diffopt=internal,filler,linematch:30\<CR>") 2682 call WriteDiffFiles(buf, ['!A', 2683 \ '!B', 2684 \ '!C' ], 2685 \ ['?Z', 2686 \ '?A', 2687 \ '?B', 2688 \ '?C', 2689 \ '?A', 2690 \ '?B', 2691 \ '?B', 2692 \ '?C']) 2693 call VerifyScreenDump(buf, 'Test_linematch_diff_grouping1', {}) 2694 call WriteDiffFiles(buf, ['!A', 2695 \ '!B', 2696 \ '!C' ], 2697 \ ['?A', 2698 \ '?Z', 2699 \ '?B', 2700 \ '?C', 2701 \ '?A', 2702 \ '?B', 2703 \ '?C', 2704 \ '?C']) 2705 call VerifyScreenDump(buf, 'Test_linematch_diff_grouping2', {}) 2706 " clean up 2707 call StopVimInTerminal(buf) 2708 endfunc 2709 2710 func Test_linematch_diff_scroll() 2711 CheckScreendump 2712 call delete('.Xdifile1.swp') 2713 call delete('.Xdifile2.swp') 2714 call WriteDiffFiles(0, [], []) 2715 let buf = RunVimInTerminal('-d Xdifile1 Xdifile2', {}) 2716 call term_sendkeys(buf, ":set autoread\<CR>\<c-w>w:set autoread\<CR>\<c-w>w") 2717 2718 " a diff that would result in multiple groups before grouping optimization 2719 call term_sendkeys(buf, ":set diffopt=internal,filler,linematch:30\<CR>") 2720 call WriteDiffFiles(buf, ['!A', 2721 \ '!B', 2722 \ '!C' ], 2723 \ ['?A', 2724 \ '?Z', 2725 \ '?B', 2726 \ '?C', 2727 \ '?A', 2728 \ '?B', 2729 \ '?C', 2730 \ '?C']) 2731 " scroll down to show calculation of top fill and scroll to correct line in 2732 " both windows 2733 call VerifyScreenDump(buf, 'Test_linematch_diff_grouping_scroll0', {}) 2734 call term_sendkeys(buf, "3\<c-e>") 2735 call VerifyScreenDump(buf, 'Test_linematch_diff_grouping_scroll1', {}) 2736 call term_sendkeys(buf, "3\<c-e>") 2737 call VerifyScreenDump(buf, 'Test_linematch_diff_grouping_scroll2', {}) 2738 " clean up 2739 call StopVimInTerminal(buf) 2740 endfunc 2741 2742 func Test_linematch_line_limit_exceeded() 2743 CheckScreendump 2744 call delete('.Xdifile1.swp') 2745 call delete('.Xdifile2.swp') 2746 call WriteDiffFiles(0, [], []) 2747 let buf = RunVimInTerminal('-d Xdifile1 Xdifile2', {}) 2748 call term_sendkeys(buf, ":set autoread\<CR>\<c-w>w:set autoread\<CR>\<c-w>w") 2749 2750 call term_sendkeys(buf, ":set diffopt=internal,filler,linematch:10\<CR>") 2751 " a diff block will not be aligned with linematch because it's contents 2752 " exceed 10 lines 2753 call WriteDiffFiles(buf, 2754 \ ['common line', 2755 \ 'HIL', 2756 \ '', 2757 \ 'aABCabc', 2758 \ 'aABCabc', 2759 \ 'aABCabc', 2760 \ 'aABCabc', 2761 \ 'common line', 2762 \ 'HIL', 2763 \ 'common line', 2764 \ 'something'], 2765 \ ['common line', 2766 \ 'DEF', 2767 \ 'GHI', 2768 \ 'something', 2769 \ '', 2770 \ 'aDEFabc', 2771 \ 'xyz', 2772 \ 'xyz', 2773 \ 'xyz', 2774 \ 'aDEFabc', 2775 \ 'aDEFabc', 2776 \ 'aDEFabc', 2777 \ 'common line', 2778 \ 'DEF', 2779 \ 'GHI', 2780 \ 'something else', 2781 \ 'common line', 2782 \ 'something']) 2783 call VerifyScreenDump(buf, 'Test_linematch_line_limit_exceeded1', {}) 2784 " after increasing the count to 30, the limit is not exceeded, and the 2785 " alignment algorithm will run on the largest diff block here 2786 call term_sendkeys(buf, ":set diffopt+=linematch:30\<CR>") 2787 call VerifyScreenDump(buf, 'Test_linematch_line_limit_exceeded2', {}) 2788 " clean up 2789 call StopVimInTerminal(buf) 2790 endfunc 2791 2792 func Test_linematch_3diffs() 2793 CheckScreendump 2794 call delete('.Xdifile1.swp') 2795 call delete('.Xdifile2.swp') 2796 call delete('.Xdifile3.swp') 2797 call WriteDiffFiles3(0, [], [], []) 2798 let buf = RunVimInTerminal('-d Xdifile1 Xdifile2 Xdifile3', {}) 2799 call term_sendkeys(buf, "1\<c-w>w:set autoread\<CR>") 2800 call term_sendkeys(buf, "2\<c-w>w:set autoread\<CR>") 2801 call term_sendkeys(buf, "3\<c-w>w:set autoread\<CR>") 2802 call term_sendkeys(buf, ":set diffopt=internal,filler,linematch:30\<CR>") 2803 call WriteDiffFiles3(buf, 2804 \ ["", 2805 \ " common line", 2806 \ " AAA", 2807 \ " AAA", 2808 \ " AAA"], 2809 \ ["", 2810 \ " common line", 2811 \ " <<<<<<< HEAD", 2812 \ " AAA", 2813 \ " AAA", 2814 \ " AAA", 2815 \ " =======", 2816 \ " BBB", 2817 \ " BBB", 2818 \ " BBB", 2819 \ " >>>>>>> branch1"], 2820 \ ["", 2821 \ " common line", 2822 \ " BBB", 2823 \ " BBB", 2824 \ " BBB"]) 2825 call VerifyScreenDump(buf, 'Test_linematch_3diffs1', {}) 2826 " clean up 2827 call StopVimInTerminal(buf) 2828 endfunc 2829 2830 " this used to access invalid memory 2831 func Test_linematch_3diffs_sanity_check() 2832 CheckScreendump 2833 call delete('.Xfile_linematch1.swp') 2834 call delete('.Xfile_linematch2.swp') 2835 call delete('.Xfile_linematch3.swp') 2836 let lines =<< trim END 2837 set diffopt=internal,filler,linematch:60 2838 call feedkeys("Aq\<esc>") 2839 call feedkeys("GAklm\<esc>") 2840 call feedkeys("o") 2841 END 2842 call writefile(lines, 'Xlinematch_3diffs.vim', 'D') 2843 call writefile(['abcd', 'def', 'hij'], 'Xfile_linematch1', 'D') 2844 call writefile(['defq', 'hijk', 'nopq'], 'Xfile_linematch2', 'D') 2845 call writefile(['hijklm', 'nopqr', 'stuv'], 'Xfile_linematch3', 'D') 2846 call WriteDiffFiles3(0, [], [], []) 2847 let buf = RunVimInTerminal('-d -S Xlinematch_3diffs.vim Xfile_linematch1 Xfile_linematch2 Xfile_linematch3', {}) 2848 call VerifyScreenDump(buf, 'Test_linematch_3diffs2', {}) 2849 2850 " clean up 2851 call StopVimInTerminal(buf) 2852 endfunc 2853 2854 func Test_diffanchors() 2855 CheckScreendump 2856 call WriteDiffFiles3(0, 2857 \ ["anchorA1", "1", "2", "3", 2858 \ "100", "101", "102", "anchorB", "103", "104", "105"], 2859 \ ["100", "101", "102", "anchorB", "103", "104", "105", 2860 \ "anchorA2", "1", "2", "3"], 2861 \ ["100", "anchorB", "103", 2862 \ "anchorA3", "1", "2", "3"]) 2863 let buf = RunVimInTerminal('-d Xdifile1 Xdifile2 Xdifile3', {}) 2864 2865 " Simple diff without any anchors 2866 call VerifyInternal(buf, "Test_diff_anchors_00", "") 2867 2868 " Setting diffopt+=anchor or diffanchors without the other won't do anything 2869 call VerifyInternal(buf, "Test_diff_anchors_00", " diffopt+=anchor") 2870 call VerifyInternal(buf, "Test_diff_anchors_00", " dia=1/anchorA/") 2871 2872 " Use a single anchor by specifying a pattern. Test both internal and 2873 " external diff to make sure both paths work. 2874 call VerifyBoth(buf, "Test_diff_anchors_01", " dia=1/anchorA/ diffopt+=anchor") 2875 2876 " Use 2 anchors. They should be sorted by line number, so in file 2/3 2877 " anchorB is used before anchorA. 2878 call VerifyBoth(buf, "Test_diff_anchors_02", " dia=1/anchorA/,1/anchorB/ diffopt+=anchor") 2879 2880 " Set marks and specify addresses using marks and repeat the test 2881 call term_sendkeys(buf, ":2wincmd w\<CR>:1/anchorA/mark a\<CR>") 2882 call term_sendkeys(buf, ":1/anchorB/mark b\<CR>") 2883 call term_sendkeys(buf, ":3wincmd w\<CR>:1/anchorA/mark a\<CR>") 2884 call term_sendkeys(buf, ":1/anchorB/mark b\<CR>") 2885 call term_sendkeys(buf, ":1wincmd w\<CR>:1/anchorA/mark a\<CR>") 2886 call term_sendkeys(buf, ":1/anchorB/mark b\<CR>") 2887 2888 call VerifyInternal(buf, "Test_diff_anchors_01", " dia='a diffopt+=anchor") 2889 call VerifyInternal(buf, "Test_diff_anchors_02", " dia='a,'b diffopt+=anchor") 2890 2891 " Update marks to point somewhere else. When we first set the mark the diff 2892 " won't be updated until we manually invoke :diffupdate. 2893 call VerifyInternal(buf, "Test_diff_anchors_01", " dia='a diffopt+=anchor") 2894 call term_sendkeys(buf, ":1wincmd w\<CR>:1/anchorB/mark a\<CR>:") 2895 call term_wait(buf) 2896 call VerifyScreenDump(buf, "Test_diff_anchors_01", {}) 2897 call term_sendkeys(buf, ":diffupdate\<CR>:") 2898 call term_wait(buf) 2899 call VerifyScreenDump(buf, "Test_diff_anchors_03", {}) 2900 2901 " Use local diff anchors with line numbers, and repeat the same test 2902 call term_sendkeys(buf, ":2wincmd w\<CR>:setlocal dia=8\<CR>") 2903 call term_sendkeys(buf, ":3wincmd w\<CR>:setlocal dia=4\<CR>") 2904 call term_sendkeys(buf, ":1wincmd w\<CR>:setlocal dia=1\<CR>") 2905 call VerifyInternal(buf, "Test_diff_anchors_01", " diffopt+=anchor") 2906 call term_sendkeys(buf, ":2wincmd w\<CR>:setlocal dia=8,4\<CR>") 2907 call term_sendkeys(buf, ":3wincmd w\<CR>:setlocal dia=4,2\<CR>") 2908 call term_sendkeys(buf, ":1wincmd w\<CR>:setlocal dia=1,8\<CR>") 2909 call VerifyInternal(buf, "Test_diff_anchors_02", " diffopt+=anchor") 2910 2911 " Test multiple diff anchors on the same line in file 1. 2912 call term_sendkeys(buf, ":1wincmd w\<CR>:setlocal dia=1,1\<CR>") 2913 call VerifyInternal(buf, "Test_diff_anchors_04", " diffopt+=anchor") 2914 2915 " Test that if one file has fewer diff anchors than others. Vim should only 2916 " use the minimum in this case. 2917 call term_sendkeys(buf, ":1wincmd w\<CR>:setlocal dia=8\<CR>") 2918 call VerifyInternal(buf, "Test_diff_anchors_05", " diffopt+=anchor") 2919 2920 " $+1 should anchor everything past the last line 2921 call term_sendkeys(buf, ":1wincmd w\<CR>:setlocal dia=$+1\<CR>") 2922 call VerifyInternal(buf, "Test_diff_anchors_06", " diffopt+=anchor") 2923 2924 " Sorting of diff anchors should work with multiple anchors 2925 call term_sendkeys(buf, ":1wincmd w\<CR>:setlocal dia=1,10,8,2\<CR>") 2926 call term_sendkeys(buf, ":2wincmd w\<CR>:setlocal dia=1,2,3,4\<CR>") 2927 call term_sendkeys(buf, ":3wincmd w\<CR>:setlocal dia=4,3,2,1\<CR>") 2928 call VerifyInternal(buf, "Test_diff_anchors_07", " diffopt+=anchor") 2929 2930 " Intentionally set an invalid anchor with wrong line number. Should fall 2931 " back to treat it as if no anchors are used at all. 2932 call term_sendkeys(buf, ":1wincmd w\<CR>:setlocal dia=1,10,8,2,1000 | silent! diffupdate\<CR>:") 2933 call VerifyScreenDump(buf, "Test_diff_anchors_00", {}) 2934 2935 call StopVimInTerminal(buf) 2936 endfunc 2937 2938 " Test that scrollbind and topline calculations work correctly, even when diff 2939 " anchors create adjacent diff blocks which complicates the calculations. 2940 func Test_diffanchors_scrollbind_topline() 2941 CheckScreendump 2942 2943 " Simple overlapped line anchored to be adjacent to each other 2944 call WriteDiffFiles(0, 2945 \ ["anchor1", "diff1a", "anchor2"], 2946 \ ["anchor1", "diff2a", "anchor2"]) 2947 let buf = RunVimInTerminal('-d Xdifile1 Xdifile2', {}) 2948 2949 call term_sendkeys(buf, ":1wincmd w\<CR>:setlocal dia=2\<CR>") 2950 call term_sendkeys(buf, ":2wincmd w\<CR>:setlocal dia=3\<CR>") 2951 2952 call VerifyInternal(buf, "Test_diff_anchors_scrollbind_topline_01", " diffopt+=anchor") 2953 call term_sendkeys(buf, "\<Esc>\<C-E>") 2954 call VerifyScreenDump(buf, "Test_diff_anchors_scrollbind_topline_02", {}) 2955 call term_sendkeys(buf, "\<C-E>") 2956 call VerifyScreenDump(buf, "Test_diff_anchors_scrollbind_topline_03", {}) 2957 call term_sendkeys(buf, "\<C-E>") 2958 call VerifyScreenDump(buf, "Test_diff_anchors_scrollbind_topline_04", {}) 2959 2960 " Also test no-filler 2961 call term_sendkeys(buf, "gg") 2962 call VerifyInternal(buf, "Test_diff_anchors_scrollbind_topline_05", " diffopt+=anchor diffopt-=filler") 2963 call term_sendkeys(buf, "\<Esc>\<C-E>") 2964 call VerifyScreenDump(buf, "Test_diff_anchors_scrollbind_topline_06", {}) 2965 call term_sendkeys(buf, "\<C-E>") 2966 call VerifyScreenDump(buf, "Test_diff_anchors_scrollbind_topline_07", {}) 2967 2968 call StopVimInTerminal(buf) 2969 endfunc 2970 2971 func Test_diffanchors_scrollbind_topline2() 2972 CheckScreendump 2973 2974 " More-complicated case with 3 files and multiple overlapping diff blocks 2975 call WriteDiffFiles3(0, 2976 \ ["anchor1"], 2977 \ ["diff2a", "diff2b", "diff2c", "diff2d", "anchor2"], 2978 \ ["diff3a", "diff3c", "diff3d", "anchor3", "diff3e"]) 2979 let buf = RunVimInTerminal('-d Xdifile1 Xdifile2 Xdifile3', {}) 2980 2981 call term_sendkeys(buf, ":1wincmd w\<CR>:setlocal dia=1,1,2\<CR>") 2982 call term_sendkeys(buf, ":2wincmd w\<CR>:setlocal dia=3,5,6\<CR>") 2983 call term_sendkeys(buf, ":3wincmd w\<CR>:setlocal dia=2,4,5\<CR>") 2984 2985 call VerifyInternal(buf, "Test_diff_anchors_scrollbind_topline_08", " diffopt+=anchor") 2986 call term_sendkeys(buf, ":1wincmd w\<CR>") 2987 call term_sendkeys(buf, "\<C-E>") 2988 call VerifyScreenDump(buf, "Test_diff_anchors_scrollbind_topline_09", {}) 2989 call term_sendkeys(buf, "\<C-E>") 2990 call VerifyScreenDump(buf, "Test_diff_anchors_scrollbind_topline_10", {}) 2991 call term_sendkeys(buf, "\<C-E>") 2992 call VerifyScreenDump(buf, "Test_diff_anchors_scrollbind_topline_11", {}) 2993 call term_sendkeys(buf, "\<C-E>") 2994 call VerifyScreenDump(buf, "Test_diff_anchors_scrollbind_topline_12", {}) 2995 2996 " Also test no-filler 2997 call term_sendkeys(buf, ":3wincmd w\<CR>gg") 2998 call VerifyInternal(buf, "Test_diff_anchors_scrollbind_topline_13", " diffopt+=anchor diffopt-=filler") 2999 call term_sendkeys(buf, "\<Esc>\<C-E>") 3000 call VerifyScreenDump(buf, "Test_diff_anchors_scrollbind_topline_14", {}) 3001 call term_sendkeys(buf, "\<C-E>") 3002 call VerifyScreenDump(buf, "Test_diff_anchors_scrollbind_topline_15", {}) 3003 call term_sendkeys(buf, "\<C-E>") 3004 call VerifyScreenDump(buf, "Test_diff_anchors_scrollbind_topline_16", {}) 3005 call term_sendkeys(buf, "\<C-E>") 3006 call VerifyScreenDump(buf, "Test_diff_anchors_scrollbind_topline_17", {}) 3007 3008 call StopVimInTerminal(buf) 3009 endfunc 3010 3011 " Test that setting 'diffanchors' will update the diff. 3012 func Test_diffanchors_option_set_update() 3013 set diffanchors='a diffopt=internal,filler,anchor 3014 3015 " Set up 3 tabs that share some buffers, and set up marks on each of them. 3016 " We want to make sure only relevant tabs are updated if buffer-local diff 3017 " anchors are updated, but all tabs should refresh if global diff anchors 3018 " are updated (see diffanchors_changed() in code). 3019 3020 " Tab 1. A buffer here will be reused. 3021 call setline(1, range(1, 10)) 3022 3mark a 3023 4mark b 3024 diffthis 3025 new 3026 call setline(1, range(21, 25)) 3027 let buf = bufnr() 3028 1mark a 3029 2mark b 3030 diffthis 3031 call assert_equal(2, diff_filler(1)) 3032 call assert_equal(0, diff_filler(2)) 3033 3034 " Tab 2. "buf" is here but intentionally not participating in diff. 3035 tabnew 3036 exec 'buf ' .. buf 3037 diffoff 3038 new 3039 call setline(1, range(31, 40)) 3040 8mark a 3041 9mark b 3042 diffthis 3043 new 3044 call setline(1, range(41, 50)) 3045 5mark a 3046 6mark b 3047 diffthis 3048 3049 call assert_equal(3, diff_filler(5)) 3050 call assert_equal(0, diff_filler(6)) 3051 call assert_equal(0, diff_filler(7)) 3052 3053 " Update mark a location, and check that the diff has *not* updated. When 3054 " updating marks diff's won't automatically update. 3055 7mark a 3056 call assert_equal(3, diff_filler(5)) 3057 call assert_equal(0, diff_filler(6)) 3058 call assert_equal(0, diff_filler(7)) 3059 3060 " Tab 3. "buf" is used here and also in a diff. 3061 tabnew 3062 call setline(1, range(51, 65)) 3063 10mark a 3064 11mark b 3065 diffthis 3066 exec 'sbuffer ' .. buf 3067 diffthis 3068 3069 " Change local diff anchor of "buf" to mark b 3070 setlocal diffanchors='b 3071 3072 " Tab 1 should immediately update the diff to use mark b because the buf 3073 " local diff anchor has been changed in "buf". 3074 1tabnext 3075 call assert_equal(0, diff_filler(1)) 3076 call assert_equal(1, diff_filler(2)) 3077 3078 " Tab 2 should not immediately update because "buf" is not a diff buffer 3079 " here. 3080 2tabnext 3081 call assert_equal(3, diff_filler(5)) 3082 call assert_equal(0, diff_filler(6)) 3083 call assert_equal(0, diff_filler(7)) 3084 3085 " Manual diff update would refresh the diff since we previously changed mark 3086 " a's location above. 3087 diffupdate 3088 call assert_equal(0, diff_filler(5)) 3089 call assert_equal(0, diff_filler(6)) 3090 call assert_equal(1, diff_filler(7)) 3091 3092 " Go back to tab 1. Reset diff anchor to global value and make sure it uses 3093 " mark a again. 3094 1tabnext 3095 set diffanchors< 3096 call assert_equal(2, diff_filler(1)) 3097 call assert_equal(0, diff_filler(2)) 3098 3099 " Now, change the global diff anchor to mark b. This should affect all tabs 3100 " including tab 2 which should update automatically. 3101 set diffanchors='b 3102 call assert_equal(0, diff_filler(1)) 3103 call assert_equal(2, diff_filler(2)) 3104 3105 2tabnext 3106 call assert_equal(0, diff_filler(5)) 3107 call assert_equal(3, diff_filler(6)) 3108 call assert_equal(0, diff_filler(7)) 3109 3110 %bw! 3111 set diffopt& 3112 set diffanchors& 3113 endfunc 3114 3115 " Test that using diff anchors with window/buffer-local addresses will work as 3116 " expected and use the relevant window/buffer instead of curbuf/curwin. 3117 func Test_diffanchors_buf_win_local_addresses() 3118 " Win 1-3 point to buffer 1. Set up different window-specific jump history 3119 " Win 2 is the one we activate diff mode on. 3120 call setline(1, range(1, 15)) 3121 norm 2gg 3122 norm 3gg 3123 3124 split 3125 norm 4gg 3126 norm 5gg 3127 3128 split 3129 norm 11gg 3130 norm 12gg 3131 call setline(10, 'new text 1') " update the '. mark to line 10 3132 3133 " Win 4 points to buffer 2 3134 botright vert new 3135 call setline(1, range(101, 110)) 3136 norm 8gg 3137 norm 9gg 3138 call setline(3, 'new text 2') " update the '. mark to line 3 3139 3140 2wincmd w 3141 diffthis 3142 4wincmd w 3143 diffthis 3144 3145 " Test buffer-local marks using '. Should be anchored to lines 10 / 3. 3146 set diffopt=internal,filler,anchor 3147 set diffanchors='. 3148 4wincmd w 3149 call assert_equal(7, diff_filler(3)) 3150 3151 " Test window-local marks using '' Should be anchored to lines 4 / 8. 3152 " Note that windows 1 & 3 point to the buffer being diff'ed but are not used 3153 " for diffing themselves and therefore should not be used. Windows 2 & 4 3154 " should be used. 3155 set diffanchors='' 3156 2wincmd w 3157 call assert_equal(4, diff_filler(4)) 3158 3159 " Also test "." for the current cursor position, which is also 3160 " window-specific. Make sure the cursor position at the longer file doesn't 3161 " result in the other file using out of bounds line number. 3162 4wincmd w 3163 norm G 3164 2wincmd w 3165 norm G 3166 set diffanchors=. 3167 diffupdate 3168 4wincmd w 3169 call assert_equal(5, diff_filler(10)) 3170 3171 %bw! 3172 set diffopt& 3173 set diffanchors& 3174 endfunc 3175 3176 " Test diff anchors error handling for anchors that fail to resolve to a line. 3177 " These are not handled during option parsing because they depend on the 3178 " specifics of the buffer at diff time. 3179 func Test_diffanchors_invalid() 3180 call setline(1, range(1, 5)) 3181 new 3182 call setline(1, range(11, 20)) 3183 set diffopt=internal,filler,anchor 3184 windo diffthis 3185 1wincmd w 3186 3187 " Line numbers that are out of bounds should be an error 3188 set diffanchors=0 3189 call assert_fails('diffupdate', 'E16:') 3190 set diffanchors=1 3191 diffupdate 3192 set diffanchors=$ 3193 diffupdate 3194 set diffanchors=$+1 3195 diffupdate 3196 set diffanchors=$+2 3197 call assert_fails('diffupdate', 'E16:') 3198 3199 " Test that non-existent marks in any one buffer will be detected 3200 set diffanchors='a 3201 call assert_fails('diffupdate', 'E20:') 3202 2mark a 3203 call assert_fails('diffupdate', 'E20:') 3204 3205 set diffanchors=1 3206 setlocal diffanchors='a 3207 diffupdate 3208 3209 set diffanchors< 3210 windo 2mark a 3211 set diffanchors='b 3212 call assert_fails('diffupdate', 'E20:') 3213 set diffanchors='a 3214 diffupdate 3215 3216 " File marks are ok to use for anchors only if it is in the same file 3217 1wincmd w 3218 3mark C 3219 setlocal diffanchors='C 3220 diffupdate 3221 set diffanchors='C 3222 call assert_fails('diffupdate', 'E20:') 3223 3224 " Buffer-local marks also can only be used in buffers that have them. 3225 set diffanchors=1 3226 exec "norm 1ggVj\<Esc>" 3227 setlocal diffanchors='< 3228 diffupdate 3229 set diffanchors='< 3230 call assert_fails('diffupdate', 'E20:') 3231 3232 " Pattern search that failed will be an error too 3233 let @/='orig_search_pat' 3234 set diffanchors=1/5/ 3235 diffupdate 3236 call assert_equal('orig_search_pat', @/) " also check we don't pollute the search register 3237 set diffanchors=1/does_not_exist/ 3238 call assert_fails('diffupdate', 'E1550:') 3239 call assert_equal('orig_search_pat', @/) 3240 3241 " Hidden buffers are not supported right now 3242 hide 3243 call assert_fails('diffupdate', 'E1562:') 3244 3245 %bw! 3246 set diffopt& 3247 set diffanchors& 3248 endfunc 3249 3250 " Test diffget/diffput behaviors when using diff anchors which could create 3251 " adjacent diff blocks. 3252 func Test_diffget_diffput_diffanchors() 3253 set diffanchors=1/anchor/ 3254 set diffopt=internal,filler,anchor 3255 3256 call setline(1, ['1', 'anchor1', '4']) 3257 diffthis 3258 new 3259 call setline(1, ['2', '3', 'anchor2', '4', '5']) 3260 diffthis 3261 wincmd w 3262 3263 " Test using no-range diffget. It should grab the closest diff block only, 3264 " even if there are multiple adjacent blocks. 3265 2 3266 diffget 3267 call assert_equal(['1', 'anchor2', '4'], getline(1, '$')) 3268 diffget 3269 call assert_equal(['2', '3', 'anchor2', '4'], getline(1, '$')) 3270 3271 " Test using a range to get/put all the adjacent diff blocks. 3272 1,$delete 3273 call setline(1, ['anchor1', '4']) 3274 0,1 diffget 3275 call assert_equal(['2', '3', 'anchor2', '4'], getline(1, '$')) 3276 3277 1,$delete 3278 call setline(1, ['anchor1', '4']) 3279 0,$+1 diffget 3280 call assert_equal(['2', '3', 'anchor2', '4', '5'], getline(1, '$')) 3281 3282 1,$delete 3283 call setline(1, ['anchor1', '4']) 3284 0,1 diffput 3285 wincmd w 3286 call assert_equal(['anchor1', '4', '5'], getline(1,'$')) 3287 3288 %bw! 3289 set diffopt& 3290 set diffanchors& 3291 endfunc 3292 3293 func Test_diff_add_prop_in_autocmd() 3294 CheckScreendump 3295 3296 let lines =<< trim END 3297 func MyDiff() abort 3298 let f1 = readfile(v:fname_in) 3299 let f2 = readfile(v:fname_new) 3300 let f0 = diff(f1, f2) 3301 call writefile(split(f0, "\n"), v:fname_out) 3302 endfunc 3303 3304 call prop_type_add('myprop', #{highlight: 'Search', override: 1}) 3305 autocmd OptionSet diff call prop_add(1, 1, #{type: 'myprop', length: 100}) 3306 set diffexpr=MyDiff() 3307 END 3308 call writefile(lines, 'Xtest_diff_add_prop_in_autocmd', 'D') 3309 call writefile(['foo', 'bar', 'baz'], 'Xdiffsplit_file', 'D') 3310 3311 let buf = RunVimInTerminal('-S Xtest_diff_add_prop_in_autocmd', {}) 3312 call term_sendkeys(buf, ":diffsplit Xdiffsplit_file\<CR>") 3313 call VerifyScreenDump(buf, 'Test_diff_add_prop_in_autocmd_01', {}) 3314 3315 call StopVimInTerminal(buf) 3316 endfunc 3317 3318 " this was causing a use-after-free by calling winframe_remove() recursively 3319 func Test_diffexpr_wipe_buffers() 3320 CheckRunVimInTerminal 3321 3322 let lines =<< trim END 3323 def DiffFuncExpr() 3324 var in: list<string> = readfile(v:fname_in) 3325 var new = readfile(v:fname_new) 3326 var out: string = diff(in, new) 3327 writefile(split(out, "n"), v:fname_out) 3328 enddef 3329 3330 new 3331 vnew 3332 set diffexpr=DiffFuncExpr() 3333 wincmd l 3334 new 3335 cal setline(1,range(20)) 3336 wind difft 3337 wincm w 3338 hid 3339 %bw! 3340 END 3341 call writefile(lines, 'Xtest_diffexpr_wipe', 'D') 3342 3343 let buf = RunVimInTerminal('Xtest_diffexpr_wipe', {}) 3344 call term_sendkeys(buf, ":so\<CR>") 3345 call WaitForAssert({-> assert_match('4 buffers wiped out', term_getline(buf, 20))}) 3346 3347 call StopVimInTerminal(buf) 3348 endfunc 3349 3350 func Test_diffput_to_empty_buf() 3351 CheckScreendump 3352 3353 let lines =<< trim END 3354 call setline(1, ['foo', 'bar', 'baz']) 3355 rightbelow vnew 3356 windo diffthis 3357 windo set cursorline nofoldenable 3358 wincmd t 3359 END 3360 call writefile(lines, 'Xtest_diffput_to_empty_buf', 'D') 3361 3362 let buf = RunVimInTerminal('-S Xtest_diffput_to_empty_buf', {}) 3363 call VerifyScreenDump(buf, 'Test_diffput_to_empty_buf_01', {}) 3364 call term_sendkeys(buf, '0') " Trigger an initial 'cursorbind' check. 3365 call VerifyScreenDump(buf, 'Test_diffput_to_empty_buf_01', {}) 3366 call term_sendkeys(buf, ":diffput | echo\<CR>") 3367 call VerifyScreenDump(buf, 'Test_diffput_to_empty_buf_02', {}) 3368 call term_sendkeys(buf, ":redraw!\<CR>") 3369 call VerifyScreenDump(buf, 'Test_diffput_to_empty_buf_02', {}) 3370 call term_sendkeys(buf, 'j') 3371 call VerifyScreenDump(buf, 'Test_diffput_to_empty_buf_03', {}) 3372 3373 call StopVimInTerminal(buf) 3374 endfunc 3375 3376 " vim: shiftwidth=2 sts=2 expandtab