1" Tests for diff mode
2
3source shared.vim
4source screendump.vim
5source check.vim
6
7func Test_diff_fold_sync()
8  enew!
9  let g:update_count = 0
10  au DiffUpdated * let g:update_count += 1
11
12  let l = range(50)
13  call setline(1, l)
14  diffthis
15  let winone = win_getid()
16  new
17  let l[25] = 'diff'
18  call setline(1, l)
19  diffthis
20  let wintwo = win_getid()
21  " line 15 is inside the closed fold
22  call assert_equal(19, foldclosedend(10))
23  call win_gotoid(winone)
24  call assert_equal(19, foldclosedend(10))
25  " open the fold
26  normal zv
27  call assert_equal(-1, foldclosedend(10))
28  " fold in other window must have opened too
29  call win_gotoid(wintwo)
30  call assert_equal(-1, foldclosedend(10))
31
32  " cursor position is in sync
33  normal 23G
34  call win_gotoid(winone)
35  call assert_equal(23, getcurpos()[1])
36
37  call assert_equal(1, g:update_count)
38  au! DiffUpdated
39
40  windo diffoff
41  close!
42  set nomodified
43endfunc
44
45func Test_vert_split()
46  set diffopt=filler
47  call Common_vert_split()
48  set diffopt&
49endfunc
50
51func Test_vert_split_internal()
52  set diffopt=internal,filler
53  call Common_vert_split()
54  set diffopt&
55endfunc
56
57func Common_vert_split()
58  " Disable the title to avoid xterm keeping the wrong one.
59  set notitle noicon
60  new
61  let l = ['1 aa', '2 bb', '3 cc', '4 dd', '5 ee']
62  call setline(1, l)
63  w! Xtest
64  normal dd
65  $
66  put
67  normal kkrXoxxx
68  w! Xtest2
69  file Nop
70  normal ggoyyyjjjozzzz
71  set foldmethod=marker foldcolumn=4
72  call assert_equal(0, &diff)
73  call assert_equal('marker', &foldmethod)
74  call assert_equal(4, &foldcolumn)
75  call assert_equal(0, &scrollbind)
76  call assert_equal(0, &cursorbind)
77  call assert_equal(1, &wrap)
78
79  vert diffsplit Xtest
80  vert diffsplit Xtest2
81  call assert_equal(1, &diff)
82  call assert_equal('diff', &foldmethod)
83  call assert_equal(2, &foldcolumn)
84  call assert_equal(1, &scrollbind)
85  call assert_equal(1, &cursorbind)
86  call assert_equal(0, &wrap)
87
88  let diff_fdm = &fdm
89  let diff_fdc = &fdc
90  " repeat entering diff mode here to see if this saves the wrong settings
91  diffthis
92  " jump to second window for a moment to have filler line appear at start of
93  " first window
94  wincmd w
95  normal gg
96  wincmd p
97  normal gg
98  call assert_equal(2, winline())
99  normal j
100  call assert_equal(4, winline())
101  normal j
102  call assert_equal(5, winline())
103  normal j
104  call assert_equal(6, winline())
105  normal j
106  call assert_equal(8, winline())
107  normal j
108  call assert_equal(9, winline())
109
110  wincmd w
111  normal gg
112  call assert_equal(1, winline())
113  normal j
114  call assert_equal(2, winline())
115  normal j
116  call assert_equal(4, winline())
117  normal j
118  call assert_equal(5, winline())
119  normal j
120  call assert_equal(8, winline())
121
122  wincmd w
123  normal gg
124  call assert_equal(2, winline())
125  normal j
126  call assert_equal(3, winline())
127  normal j
128  call assert_equal(4, winline())
129  normal j
130  call assert_equal(5, winline())
131  normal j
132  call assert_equal(6, winline())
133  normal j
134  call assert_equal(7, winline())
135  normal j
136  call assert_equal(8, winline())
137
138  " Test diffoff
139  diffoff!
140  1wincmd 2
141  let &diff = 1
142  let &fdm = diff_fdm
143  let &fdc = diff_fdc
144  4wincmd w
145  diffoff!
146  1wincmd w
147  call assert_equal(0, &diff)
148  call assert_equal('marker', &foldmethod)
149  call assert_equal(4, &foldcolumn)
150  call assert_equal(0, &scrollbind)
151  call assert_equal(0, &cursorbind)
152  call assert_equal(1, &wrap)
153
154  wincmd w
155  call assert_equal(0, &diff)
156  call assert_equal('marker', &foldmethod)
157  call assert_equal(4, &foldcolumn)
158  call assert_equal(0, &scrollbind)
159  call assert_equal(0, &cursorbind)
160  call assert_equal(1, &wrap)
161
162  wincmd w
163  call assert_equal(0, &diff)
164  call assert_equal('marker', &foldmethod)
165  call assert_equal(4, &foldcolumn)
166  call assert_equal(0, &scrollbind)
167  call assert_equal(0, &cursorbind)
168  call assert_equal(1, &wrap)
169
170  call delete('Xtest')
171  call delete('Xtest2')
172  windo bw!
173endfunc
174
175func Test_filler_lines()
176  " Test that diffing shows correct filler lines
177  enew!
178  put =range(4,10)
179  1d _
180  vnew
181  put =range(1,10)
182  1d _
183  windo diffthis
184  wincmd h
185  call assert_equal(1, line('w0'))
186  unlet! diff_fdm diff_fdc
187  windo diffoff
188  bwipe!
189  enew!
190endfunc
191
192func Test_diffget_diffput()
193  enew!
194  let l = range(50)
195  call setline(1, l)
196  call assert_fails('diffget', 'E99:')
197  diffthis
198  call assert_fails('diffget', 'E100:')
199  new
200  let l[10] = 'one'
201  let l[20] = 'two'
202  let l[30] = 'three'
203  let l[40] = 'four'
204  call setline(1, l)
205  diffthis
206  call assert_equal('one', getline(11))
207  11diffget
208  call assert_equal('10', getline(11))
209  21diffput
210  wincmd w
211  call assert_equal('two', getline(21))
212  normal 31Gdo
213  call assert_equal('three', getline(31))
214  call assert_equal('40', getline(41))
215  normal 41Gdp
216  wincmd w
217  call assert_equal('40', getline(41))
218  new
219  diffthis
220  call assert_fails('diffget', 'E101:')
221
222  windo diffoff
223  %bwipe!
224endfunc
225
226" Test putting two changes from one buffer to another
227func Test_diffput_two()
228  new a
229  let win_a = win_getid()
230  call setline(1, range(1, 10))
231  diffthis
232  new b
233  let win_b = win_getid()
234  call setline(1, range(1, 10))
235  8del
236  5del
237  diffthis
238  call win_gotoid(win_a)
239  %diffput
240  call win_gotoid(win_b)
241  call assert_equal(map(range(1, 10), 'string(v:val)'), getline(1, '$'))
242  bwipe! a
243  bwipe! b
244endfunc
245
246" Test for :diffget/:diffput with a range that is inside a diff chunk
247func Test_diffget_diffput_range()
248  call setline(1, range(1, 10))
249  new
250  call setline(1, range(11, 20))
251  windo diffthis
252  3,5diffget
253  call assert_equal(['13', '14', '15'], getline(3, 5))
254  call setline(1, range(1, 10))
255  4,8diffput
256  wincmd p
257  call assert_equal(['13', '4', '5', '6', '7', '8', '19'], getline(3, 9))
258  %bw!
259endfunc
260
261" Test for :diffget/:diffput with an empty buffer and a non-empty buffer
262func Test_diffget_diffput_empty_buffer()
263  %d _
264  new
265  call setline(1, 'one')
266  windo diffthis
267  diffget
268  call assert_equal(['one'], getline(1, '$'))
269  %d _
270  diffput
271  wincmd p
272  call assert_equal([''], getline(1, '$'))
273  %bw!
274endfunc
275
276" :diffput and :diffget completes names of buffers which
277" are in diff mode and which are different then current buffer.
278" No completion when the current window is not in diff mode.
279func Test_diffget_diffput_completion()
280  e            Xdiff1 | diffthis
281  botright new Xdiff2
282  botright new Xdiff3 | split | diffthis
283  botright new Xdiff4 | diffthis
284
285  wincmd t
286  call assert_equal('Xdiff1', bufname('%'))
287  call feedkeys(":diffput \<C-A>\<C-B>\"\<CR>", 'tx')
288  call assert_equal('"diffput Xdiff3 Xdiff4', @:)
289  call feedkeys(":diffget \<C-A>\<C-B>\"\<CR>", 'tx')
290  call assert_equal('"diffget Xdiff3 Xdiff4', @:)
291  call assert_equal(['Xdiff3', 'Xdiff4'], getcompletion('', 'diff_buffer'))
292
293  " Xdiff2 is not in diff mode, so no completion for :diffput, :diffget
294  wincmd j
295  call assert_equal('Xdiff2', bufname('%'))
296  call feedkeys(":diffput \<C-A>\<C-B>\"\<CR>", 'tx')
297  call assert_equal('"diffput ', @:)
298  call feedkeys(":diffget \<C-A>\<C-B>\"\<CR>", 'tx')
299  call assert_equal('"diffget ', @:)
300  call assert_equal([], getcompletion('', 'diff_buffer'))
301
302  " Xdiff3 is split in 2 windows, only the top one is in diff mode.
303  " So completion of :diffput :diffget only happens in the top window.
304  wincmd j
305  call assert_equal('Xdiff3', bufname('%'))
306  call assert_equal(1, &diff)
307  call feedkeys(":diffput \<C-A>\<C-B>\"\<CR>", 'tx')
308  call assert_equal('"diffput Xdiff1 Xdiff4', @:)
309  call feedkeys(":diffget \<C-A>\<C-B>\"\<CR>", 'tx')
310  call assert_equal('"diffget Xdiff1 Xdiff4', @:)
311  call assert_equal(['Xdiff1', 'Xdiff4'], getcompletion('', 'diff_buffer'))
312
313  wincmd j
314  call assert_equal('Xdiff3', bufname('%'))
315  call assert_equal(0, &diff)
316  call feedkeys(":diffput \<C-A>\<C-B>\"\<CR>", 'tx')
317  call assert_equal('"diffput ', @:)
318  call feedkeys(":diffget \<C-A>\<C-B>\"\<CR>", 'tx')
319  call assert_equal('"diffget ', @:)
320  call assert_equal([], getcompletion('', 'diff_buffer'))
321
322  wincmd j
323  call assert_equal('Xdiff4', bufname('%'))
324  call feedkeys(":diffput \<C-A>\<C-B>\"\<CR>", 'tx')
325  call assert_equal('"diffput Xdiff1 Xdiff3', @:)
326  call feedkeys(":diffget \<C-A>\<C-B>\"\<CR>", 'tx')
327  call assert_equal('"diffget Xdiff1 Xdiff3', @:)
328  call assert_equal(['Xdiff1', 'Xdiff3'], getcompletion('', 'diff_buffer'))
329
330  %bwipe
331endfunc
332
333func Test_dp_do_buffer()
334  e! one
335  let bn1=bufnr('%')
336  let l = range(60)
337  call setline(1, l)
338  diffthis
339
340  new two
341  let l[10] = 'one'
342  let l[20] = 'two'
343  let l[30] = 'three'
344  let l[40] = 'four'
345  let l[50] = 'five'
346  call setline(1, l)
347  diffthis
348
349  " dp and do with invalid buffer number.
350  11
351  call assert_fails('norm 99999dp', 'E102:')
352  call assert_fails('norm 99999do', 'E102:')
353  call assert_fails('diffput non_existing_buffer', 'E94:')
354  call assert_fails('diffget non_existing_buffer', 'E94:')
355
356  " dp and do with valid buffer number.
357  call assert_equal('one', getline('.'))
358  exe 'norm ' . bn1 . 'do'
359  call assert_equal('10', getline('.'))
360  21
361  call assert_equal('two', getline('.'))
362  diffget one
363  call assert_equal('20', getline('.'))
364
365  31
366  exe 'norm ' . bn1 . 'dp'
367  41
368  diffput one
369  wincmd w
370  31
371  call assert_equal('three', getline('.'))
372  41
373  call assert_equal('four', getline('.'))
374
375  " dp and do with buffer number which is not in diff mode.
376  new not_in_diff_mode
377  let bn3=bufnr('%')
378  wincmd w
379  51
380  call assert_fails('exe "norm" . bn3 . "dp"', 'E103:')
381  call assert_fails('exe "norm" . bn3 . "do"', 'E103:')
382  call assert_fails('diffput not_in_diff_mode', 'E94:')
383  call assert_fails('diffget not_in_diff_mode', 'E94:')
384
385  windo diffoff
386  %bwipe!
387endfunc
388
389func Test_do_lastline()
390  e! one
391  call setline(1, ['1','2','3','4','5','6'])
392  diffthis
393
394  new two
395  call setline(1, ['2','4','5'])
396  diffthis
397
398  1
399  norm dp]c
400  norm dp]c
401  wincmd w
402  call assert_equal(4, line('$'))
403  norm G
404  norm do
405  call assert_equal(3, line('$'))
406
407  windo diffoff
408  %bwipe!
409endfunc
410
411func Test_diffoff()
412  enew!
413  call setline(1, ['Two', 'Three'])
414  redraw
415  let normattr = screenattr(1, 1)
416  diffthis
417  botright vert new
418  call setline(1, ['One', '', 'Two', 'Three'])
419  diffthis
420  redraw
421  call assert_notequal(normattr, 1->screenattr(1))
422  diffoff!
423  redraw
424  call assert_equal(normattr, screenattr(1, 1))
425  bwipe!
426  bwipe!
427endfunc
428
429func Common_icase_test()
430  edit one
431  call setline(1, ['One', 'Two', 'Three', 'Four', 'Fi#ve'])
432  redraw
433  let normattr = screenattr(1, 1)
434  diffthis
435
436  botright vert new two
437  call setline(1, ['one', 'TWO', 'Three ', 'Four', 'fI=VE'])
438  diffthis
439
440  redraw
441  call assert_equal(normattr, screenattr(1, 1))
442  call assert_equal(normattr, screenattr(2, 1))
443  call assert_notequal(normattr, screenattr(3, 1))
444  call assert_equal(normattr, screenattr(4, 1))
445
446  let dtextattr = screenattr(5, 3)
447  call assert_notequal(dtextattr, screenattr(5, 1))
448  call assert_notequal(dtextattr, screenattr(5, 5))
449
450  diffoff!
451  %bwipe!
452endfunc
453
454func Test_diffopt_icase()
455  set diffopt=icase,foldcolumn:0
456  call Common_icase_test()
457  set diffopt&
458endfunc
459
460func Test_diffopt_icase_internal()
461  set diffopt=icase,foldcolumn:0,internal
462  call Common_icase_test()
463  set diffopt&
464endfunc
465
466func Common_iwhite_test()
467  edit one
468  " Difference in trailing spaces and amount of spaces should be ignored,
469  " but not other space differences.
470  call setline(1, ["One \t", 'Two', 'Three', 'one two', 'one two', 'Four'])
471  redraw
472  let normattr = screenattr(1, 1)
473  diffthis
474
475  botright vert new two
476  call setline(1, ["One\t ", "Two\t ", 'Three', 'one   two', 'onetwo', ' Four'])
477  diffthis
478
479  redraw
480  call assert_equal(normattr, screenattr(1, 1))
481  call assert_equal(normattr, screenattr(2, 1))
482  call assert_equal(normattr, screenattr(3, 1))
483  call assert_equal(normattr, screenattr(4, 1))
484  call assert_notequal(normattr, screenattr(5, 1))
485  call assert_notequal(normattr, screenattr(6, 1))
486
487  diffoff!
488  %bwipe!
489endfunc
490
491func Test_diffopt_iwhite()
492  set diffopt=iwhite,foldcolumn:0
493  call Common_iwhite_test()
494  set diffopt&
495endfunc
496
497func Test_diffopt_iwhite_internal()
498  set diffopt=internal,iwhite,foldcolumn:0
499  call Common_iwhite_test()
500  set diffopt&
501endfunc
502
503func Test_diffopt_context()
504  enew!
505  call setline(1, ['1', '2', '3', '4', '5', '6', '7'])
506  diffthis
507  new
508  call setline(1, ['1', '2', '3', '4', '5x', '6', '7'])
509  diffthis
510
511  set diffopt=context:2
512  call assert_equal('+--  2 lines: 1', foldtextresult(1))
513  set diffopt=internal,context:2
514  call assert_equal('+--  2 lines: 1', foldtextresult(1))
515
516  set diffopt=context:1
517  call assert_equal('+--  3 lines: 1', foldtextresult(1))
518  set diffopt=internal,context:1
519  call assert_equal('+--  3 lines: 1', foldtextresult(1))
520
521  diffoff!
522  %bwipe!
523  set diffopt&
524endfunc
525
526func Test_diffopt_horizontal()
527  set diffopt=internal,horizontal
528  diffsplit
529
530  call assert_equal(&columns, winwidth(1))
531  call assert_equal(&columns, winwidth(2))
532  call assert_equal(&lines, winheight(1) + winheight(2) + 3)
533  call assert_inrange(0, 1, winheight(1) - winheight(2))
534
535  set diffopt&
536  diffoff!
537  %bwipe
538endfunc
539
540func Test_diffopt_vertical()
541  set diffopt=internal,vertical
542  diffsplit
543
544  call assert_equal(&lines - 2, winheight(1))
545  call assert_equal(&lines - 2, winheight(2))
546  call assert_equal(&columns, winwidth(1) + winwidth(2) + 1)
547  call assert_inrange(0, 1, winwidth(1) - winwidth(2))
548
549  set diffopt&
550  diffoff!
551  %bwipe
552endfunc
553
554func Test_diffopt_hiddenoff()
555  set diffopt=internal,filler,foldcolumn:0,hiddenoff
556  e! one
557  call setline(1, ['Two', 'Three'])
558  redraw
559  let normattr = screenattr(1, 1)
560  diffthis
561  botright vert new two
562  call setline(1, ['One', 'Four'])
563  diffthis
564  redraw
565  call assert_notequal(normattr, screenattr(1, 1))
566  set hidden
567  close
568  redraw
569  " should not diffing with hidden buffer two while 'hiddenoff' is enabled
570  call assert_equal(normattr, screenattr(1, 1))
571
572  bwipe!
573  bwipe!
574  set hidden& diffopt&
575endfunc
576
577func Test_diffoff_hidden()
578  set diffopt=internal,filler,foldcolumn:0
579  e! one
580  call setline(1, ['Two', 'Three'])
581  redraw
582  let normattr = screenattr(1, 1)
583  diffthis
584  botright vert new two
585  call setline(1, ['One', 'Four'])
586  diffthis
587  redraw
588  call assert_notequal(normattr, screenattr(1, 1))
589  set hidden
590  close
591  redraw
592  " diffing with hidden buffer two
593  call assert_notequal(normattr, screenattr(1, 1))
594  diffoff
595  redraw
596  call assert_equal(normattr, screenattr(1, 1))
597  diffthis
598  redraw
599  " still diffing with hidden buffer two
600  call assert_notequal(normattr, screenattr(1, 1))
601  diffoff!
602  redraw
603  call assert_equal(normattr, screenattr(1, 1))
604  diffthis
605  redraw
606  " no longer diffing with hidden buffer two
607  call assert_equal(normattr, screenattr(1, 1))
608
609  bwipe!
610  bwipe!
611  set hidden& diffopt&
612endfunc
613
614func Test_setting_cursor()
615  new Xtest1
616  put =range(1,90)
617  wq
618  new Xtest2
619  put =range(1,100)
620  wq
621
622  tabe Xtest2
623  $
624  diffsp Xtest1
625  tabclose
626
627  call delete('Xtest1')
628  call delete('Xtest2')
629endfunc
630
631func Test_diff_move_to()
632  new
633  call setline(1, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
634  diffthis
635  vnew
636  call setline(1, [1, '2x', 3, 4, 4, 5, '6x', 7, '8x', 9, '10x'])
637  diffthis
638  norm ]c
639  call assert_equal(2, line('.'))
640  norm 3]c
641  call assert_equal(9, line('.'))
642  norm 10]c
643  call assert_equal(11, line('.'))
644  norm [c
645  call assert_equal(9, line('.'))
646  norm 2[c
647  call assert_equal(5, line('.'))
648  norm 10[c
649  call assert_equal(2, line('.'))
650  %bwipe!
651endfunc
652
653func Test_diffexpr()
654  CheckExecutable diff
655
656  func DiffExpr()
657    " Prepend some text to check diff type detection
658    call writefile(['warning', '  message'], v:fname_out)
659    silent exe '!diff ' . v:fname_in . ' ' . v:fname_new . '>>' . v:fname_out
660  endfunc
661  set diffexpr=DiffExpr()
662  set diffopt=foldcolumn:0
663
664  enew!
665  call setline(1, ['one', 'two', 'three'])
666  redraw
667  let normattr = screenattr(1, 1)
668  diffthis
669
670  botright vert new
671  call setline(1, ['one', 'two', 'three.'])
672  diffthis
673
674  redraw
675  call assert_equal(normattr, screenattr(1, 1))
676  call assert_equal(normattr, screenattr(2, 1))
677  call assert_notequal(normattr, screenattr(3, 1))
678  diffoff!
679
680  " Try using an non-existing function for 'diffexpr'.
681  set diffexpr=NewDiffFunc()
682  call assert_fails('windo diffthis', ['E117:', 'E97:'])
683  diffoff!
684  %bwipe!
685  set diffexpr& diffopt&
686endfunc
687
688func Test_diffpatch()
689  " The patch program on MS-Windows may fail or hang.
690  CheckExecutable patch
691  CheckUnix
692  new
693  insert
694***************
695*** 1,3 ****
696  1
697! 2
698  3
699--- 1,4 ----
700  1
701! 2x
702  3
703+ 4
704.
705  saveas! Xpatch
706  bwipe!
707  new
708  call assert_fails('diffpatch Xpatch', 'E816:')
709
710  for name in ['Xpatch', 'Xpatch$HOME', 'Xpa''tch']
711    call setline(1, ['1', '2', '3'])
712    if name != 'Xpatch'
713      call rename('Xpatch', name)
714    endif
715    exe 'diffpatch ' . escape(name, '$')
716    call assert_equal(['1', '2x', '3', '4'], getline(1, '$'))
717    if name != 'Xpatch'
718      call rename(name, 'Xpatch')
719    endif
720    bwipe!
721  endfor
722
723  call delete('Xpatch')
724  bwipe!
725endfunc
726
727func Test_diff_too_many_buffers()
728  for i in range(1, 8)
729    exe "new Xtest" . i
730    diffthis
731  endfor
732  new Xtest9
733  call assert_fails('diffthis', 'E96:')
734  %bwipe!
735endfunc
736
737func Test_diff_nomodifiable()
738  new
739  call setline(1, [1, 2, 3, 4])
740  setl nomodifiable
741  diffthis
742  vnew
743  call setline(1, ['1x', 2, 3, 3, 4])
744  diffthis
745  call assert_fails('norm dp', 'E793:')
746  setl nomodifiable
747  call assert_fails('norm do', 'E21:')
748  %bwipe!
749endfunc
750
751func Test_diff_hlID()
752  new
753  call setline(1, [1, 2, 3])
754  diffthis
755  vnew
756  call setline(1, ['1x', 2, 'x', 3])
757  diffthis
758  redraw
759
760  call diff_hlID(-1, 1)->synIDattr("name")->assert_equal("")
761
762  call diff_hlID(1, 1)->synIDattr("name")->assert_equal("DiffChange")
763  call diff_hlID(1, 2)->synIDattr("name")->assert_equal("DiffText")
764  call diff_hlID(2, 1)->synIDattr("name")->assert_equal("")
765  call diff_hlID(3, 1)->synIDattr("name")->assert_equal("DiffAdd")
766  eval 4->diff_hlID(1)->synIDattr("name")->assert_equal("")
767
768  wincmd w
769  call assert_equal(synIDattr(diff_hlID(1, 1), "name"), "DiffChange")
770  call assert_equal(synIDattr(diff_hlID(2, 1), "name"), "")
771  call assert_equal(synIDattr(diff_hlID(3, 1), "name"), "")
772
773  %bwipe!
774endfunc
775
776func Test_diff_filler()
777  new
778  call setline(1, [1, 2, 3, 'x', 4])
779  diffthis
780  vnew
781  call setline(1, [1, 2, 'y', 'y', 3, 4])
782  diffthis
783  redraw
784
785  call assert_equal([0, 0, 0, 0, 0, 0, 0, 1, 0], map(range(-1, 7), 'v:val->diff_filler()'))
786  wincmd w
787  call assert_equal([0, 0, 0, 0, 2, 0, 0, 0], map(range(-1, 6), 'diff_filler(v:val)'))
788
789  %bwipe!
790endfunc
791
792func Test_diff_lastline()
793  enew!
794  only!
795  call setline(1, ['This is a ', 'line with five ', 'rows'])
796  diffthis
797  botright vert new
798  call setline(1, ['This is', 'a line with ', 'four rows'])
799  diffthis
800  1
801  call feedkeys("Je a\<CR>", 'tx')
802  call feedkeys("Je a\<CR>", 'tx')
803  let w1lines = winline()
804  wincmd w
805  $
806  let w2lines = winline()
807  call assert_equal(w2lines, w1lines)
808  bwipe!
809  bwipe!
810endfunc
811
812func WriteDiffFiles(buf, list1, list2)
813  call writefile(a:list1, 'Xfile1')
814  call writefile(a:list2, 'Xfile2')
815  if a:buf
816    call term_sendkeys(a:buf, ":checktime\<CR>")
817  endif
818endfunc
819
820" Verify a screendump with both the internal and external diff.
821func VerifyBoth(buf, dumpfile, extra)
822  " trailing : for leaving the cursor on the command line
823  for cmd in [":set diffopt=filler" . a:extra . "\<CR>:", ":set diffopt+=internal\<CR>:"]
824    call term_sendkeys(a:buf, cmd)
825    if VerifyScreenDump(a:buf, a:dumpfile, {}, cmd =~ 'internal' ? 'internal' : 'external')
826      " don't let the next iteration overwrite the "failed" file.
827      return
828    endif
829  endfor
830
831  " also test unified diff
832  call term_sendkeys(a:buf, ":call SetupUnified()\<CR>:")
833  call term_sendkeys(a:buf, ":redraw!\<CR>:")
834  call VerifyScreenDump(a:buf, a:dumpfile, {}, 'unified')
835  call term_sendkeys(a:buf, ":call StopUnified()\<CR>:")
836endfunc
837
838" Verify a screendump with the internal diff only.
839func VerifyInternal(buf, dumpfile, extra)
840  call term_sendkeys(a:buf, ":diffupdate!\<CR>")
841  " trailing : for leaving the cursor on the command line
842  call term_sendkeys(a:buf, ":set diffopt=internal,filler" . a:extra . "\<CR>:")
843  call TermWait(a:buf)
844  call VerifyScreenDump(a:buf, a:dumpfile, {})
845endfunc
846
847func Test_diff_screen()
848  let g:test_is_flaky = 1
849  CheckScreendump
850  CheckFeature menu
851
852  let lines =<< trim END
853      func UnifiedDiffExpr()
854        " Prepend some text to check diff type detection
855        call writefile(['warning', '  message'], v:fname_out)
856        silent exe '!diff -U0 ' .. v:fname_in .. ' ' .. v:fname_new .. '>>' .. v:fname_out
857      endfunc
858      func SetupUnified()
859        set diffexpr=UnifiedDiffExpr()
860        diffupdate
861      endfunc
862      func StopUnified()
863        set diffexpr=
864      endfunc
865  END
866  call writefile(lines, 'XdiffSetup')
867
868  " clean up already existing swap files, just in case
869  call delete('.Xfile1.swp')
870  call delete('.Xfile2.swp')
871
872  " Test 1: Add a line in beginning of file 2
873  call WriteDiffFiles(0, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
874  let buf = RunVimInTerminal('-d -S XdiffSetup Xfile1 Xfile2', {})
875  " Set autoread mode, so that Vim won't complain once we re-write the test
876  " files
877  call term_sendkeys(buf, ":set autoread\<CR>\<c-w>w:set autoread\<CR>\<c-w>w")
878
879  call VerifyBoth(buf, 'Test_diff_01', '')
880
881  " Test 2: Add a line in beginning of file 1
882  call WriteDiffFiles(buf, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
883  call VerifyBoth(buf, 'Test_diff_02', '')
884
885  " Test 3: Add a line at the end of file 2
886  call WriteDiffFiles(buf, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
887  call VerifyBoth(buf, 'Test_diff_03', '')
888
889  " Test 4: Add a line at the end of file 1
890  call WriteDiffFiles(buf, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
891  call VerifyBoth(buf, 'Test_diff_04', '')
892
893  " Test 5: Add a line in the middle of file 2, remove on at the end of file 1
894  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])
895  call VerifyBoth(buf, 'Test_diff_05', '')
896
897  " Test 6: Add a line in the middle of file 1, remove on at the end of file 2
898  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])
899  call VerifyBoth(buf, 'Test_diff_06', '')
900
901  " Variants on test 6 with different context settings
902  call term_sendkeys(buf, ":set diffopt+=context:2\<cr>")
903  call VerifyScreenDump(buf, 'Test_diff_06.2', {})
904  call term_sendkeys(buf, ":set diffopt-=context:2\<cr>")
905  call term_sendkeys(buf, ":set diffopt+=context:1\<cr>")
906  call VerifyScreenDump(buf, 'Test_diff_06.1', {})
907  call term_sendkeys(buf, ":set diffopt-=context:1\<cr>")
908  call term_sendkeys(buf, ":set diffopt+=context:0\<cr>")
909  call VerifyScreenDump(buf, 'Test_diff_06.0', {})
910  call term_sendkeys(buf, ":set diffopt-=context:0\<cr>")
911
912  " Test 7 - 9: Test normal/patience/histogram diff algorithm
913  call WriteDiffFiles(buf, ['#include <stdio.h>', '', '// Frobs foo heartily', 'int frobnitz(int foo)', '{',
914      \ '    int i;', '    for(i = 0; i < 10; i++)', '    {', '        printf("Your answer is: ");',
915      \ '        printf("%d\n", foo);', '    }', '}', '', 'int fact(int n)', '{', '    if(n > 1)', '    {',
916      \ '        return fact(n-1) * n;', '    }', '    return 1;', '}', '', 'int main(int argc, char **argv)',
917      \ '{', '    frobnitz(fact(10));', '}'],
918      \ ['#include <stdio.h>', '', 'int fib(int n)', '{', '    if(n > 2)', '    {',
919      \ '        return fib(n-1) + fib(n-2);', '    }', '    return 1;', '}', '', '// Frobs foo heartily',
920      \ 'int frobnitz(int foo)', '{', '    int i;', '    for(i = 0; i < 10; i++)', '    {',
921      \ '        printf("%d\n", foo);', '    }', '}', '',
922      \ 'int main(int argc, char **argv)', '{', '    frobnitz(fib(10));', '}'])
923  call term_sendkeys(buf, ":diffupdate!\<cr>")
924  call term_sendkeys(buf, ":set diffopt+=internal\<cr>")
925  call VerifyScreenDump(buf, 'Test_diff_07', {})
926
927  call term_sendkeys(buf, ":set diffopt+=algorithm:patience\<cr>")
928  call VerifyScreenDump(buf, 'Test_diff_08', {})
929
930  call term_sendkeys(buf, ":set diffopt+=algorithm:histogram\<cr>")
931  call VerifyScreenDump(buf, 'Test_diff_09', {})
932
933  " Test 10-11: normal/indent-heuristic
934  call term_sendkeys(buf, ":set diffopt&vim\<cr>")
935  call WriteDiffFiles(buf, ['', '  def finalize(values)', '', '    values.each do |v|', '      v.finalize', '    end'],
936      \ ['', '  def finalize(values)', '', '    values.each do |v|', '      v.prepare', '    end', '',
937      \ '    values.each do |v|', '      v.finalize', '    end'])
938  call term_sendkeys(buf, ":diffupdate!\<cr>")
939  call term_sendkeys(buf, ":set diffopt+=internal\<cr>")
940  call VerifyScreenDump(buf, 'Test_diff_10', {})
941
942  " Leave trailing : at commandline!
943  call term_sendkeys(buf, ":set diffopt+=indent-heuristic\<cr>:\<cr>")
944  call VerifyScreenDump(buf, 'Test_diff_11', {}, 'one')
945  " shouldn't matter, if indent-algorithm comes before or after the algorithm
946  call term_sendkeys(buf, ":set diffopt&\<cr>")
947  call term_sendkeys(buf, ":set diffopt+=indent-heuristic,algorithm:patience\<cr>:\<cr>")
948  call VerifyScreenDump(buf, 'Test_diff_11', {}, 'two')
949  call term_sendkeys(buf, ":set diffopt&\<cr>")
950  call term_sendkeys(buf, ":set diffopt+=algorithm:patience,indent-heuristic\<cr>:\<cr>")
951  call VerifyScreenDump(buf, 'Test_diff_11', {}, 'three')
952
953  " Test 12: diff the same file
954  call WriteDiffFiles(buf, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
955  call VerifyBoth(buf, 'Test_diff_12', '')
956
957  " Test 13: diff an empty file
958  call WriteDiffFiles(buf, [], [])
959  call VerifyBoth(buf, 'Test_diff_13', '')
960
961  " Test 14: test diffopt+=icase
962  call WriteDiffFiles(buf, ['a', 'b', 'cd'], ['A', 'b', 'cDe'])
963  call VerifyBoth(buf, 'Test_diff_14', " diffopt+=filler diffopt+=icase")
964
965  " Test 15-16: test diffopt+=iwhite
966  call WriteDiffFiles(buf, ['int main()', '{', '   printf("Hello, World!");', '   return 0;', '}'],
967      \ ['int main()', '{', '   if (0)', '   {', '      printf("Hello, World!");', '      return 0;', '   }', '}'])
968  call term_sendkeys(buf, ":diffupdate!\<cr>")
969  call term_sendkeys(buf, ":set diffopt&vim diffopt+=filler diffopt+=iwhite\<cr>")
970  call VerifyScreenDump(buf, 'Test_diff_15', {})
971  call term_sendkeys(buf, ":set diffopt+=internal\<cr>")
972  call VerifyScreenDump(buf, 'Test_diff_16', {})
973
974  " Test 17: test diffopt+=iblank
975  call WriteDiffFiles(buf, ['a', ' ', 'cd', 'ef', 'xxx'], ['a', 'cd', '', 'ef', 'yyy'])
976  call VerifyInternal(buf, 'Test_diff_17', " diffopt+=iblank")
977
978  " Test 18: test diffopt+=iblank,iwhite / iwhiteall / iwhiteeol
979  call VerifyInternal(buf, 'Test_diff_18', " diffopt+=iblank,iwhite")
980  call VerifyInternal(buf, 'Test_diff_18', " diffopt+=iblank,iwhiteall")
981  call VerifyInternal(buf, 'Test_diff_18', " diffopt+=iblank,iwhiteeol")
982
983  " Test 19: test diffopt+=iwhiteeol
984  call WriteDiffFiles(buf, ['a ', 'x', 'cd', 'ef', 'xx  xx', 'foo', 'bar'], ['a', 'x', 'c d', ' ef', 'xx xx', 'foo', '', 'bar'])
985  call VerifyInternal(buf, 'Test_diff_19', " diffopt+=iwhiteeol")
986
987  " Test 19: test diffopt+=iwhiteall
988  call VerifyInternal(buf, 'Test_diff_20', " diffopt+=iwhiteall")
989
990  " clean up
991  call StopVimInTerminal(buf)
992  call delete('Xfile1')
993  call delete('Xfile2')
994  call delete('XdiffSetup')
995endfunc
996
997func Test_diff_with_scroll_and_change()
998  CheckScreendump
999
1000  let lines =<< trim END
1001	call setline(1, range(1, 15))
1002	vnew
1003	call setline(1, range(9, 15))
1004	windo diffthis
1005	wincmd h
1006	exe "normal Gl5\<C-E>"
1007  END
1008  call writefile(lines, 'Xtest_scroll_change')
1009  let buf = RunVimInTerminal('-S Xtest_scroll_change', {})
1010
1011  call VerifyScreenDump(buf, 'Test_diff_scroll_change_01', {})
1012
1013  call term_sendkeys(buf, "ax\<Esc>")
1014  call VerifyScreenDump(buf, 'Test_diff_scroll_change_02', {})
1015
1016  call term_sendkeys(buf, "\<C-W>lay\<Esc>")
1017  call VerifyScreenDump(buf, 'Test_diff_scroll_change_03', {})
1018
1019  " clean up
1020  call StopVimInTerminal(buf)
1021  call delete('Xtest_scroll_change')
1022endfunc
1023
1024func Test_diff_with_cursorline()
1025  CheckScreendump
1026
1027  call writefile([
1028	\ 'hi CursorLine ctermbg=red ctermfg=white',
1029	\ 'set cursorline',
1030	\ 'call setline(1, ["foo","foo","foo","bar"])',
1031	\ 'vnew',
1032	\ 'call setline(1, ["bee","foo","foo","baz"])',
1033	\ 'windo diffthis',
1034	\ '2wincmd w',
1035	\ ], 'Xtest_diff_cursorline')
1036  let buf = RunVimInTerminal('-S Xtest_diff_cursorline', {})
1037
1038  call VerifyScreenDump(buf, 'Test_diff_with_cursorline_01', {})
1039  call term_sendkeys(buf, "j")
1040  call VerifyScreenDump(buf, 'Test_diff_with_cursorline_02', {})
1041  call term_sendkeys(buf, "j")
1042  call VerifyScreenDump(buf, 'Test_diff_with_cursorline_03', {})
1043
1044  " clean up
1045  call StopVimInTerminal(buf)
1046  call delete('Xtest_diff_cursorline')
1047endfunc
1048
1049func Test_diff_with_cursorline_breakindent()
1050  CheckScreendump
1051
1052  call writefile([
1053	\ 'hi CursorLine ctermbg=red ctermfg=white',
1054	\ 'set noequalalways wrap diffopt=followwrap cursorline breakindent',
1055	\ '50vnew',
1056	\ 'call setline(1, ["  ","  ","  ","  "])',
1057	\ 'exe "norm 20Afoo\<Esc>j20Afoo\<Esc>j20Afoo\<Esc>j20Abar\<Esc>"',
1058	\ 'vnew',
1059	\ 'call setline(1, ["  ","  ","  ","  "])',
1060	\ 'exe "norm 20Abee\<Esc>j20Afoo\<Esc>j20Afoo\<Esc>j20Abaz\<Esc>"',
1061	\ 'windo diffthis',
1062	\ '2wincmd w',
1063	\ ], 'Xtest_diff_cursorline_breakindent')
1064  let buf = RunVimInTerminal('-S Xtest_diff_cursorline_breakindent', {})
1065
1066  call term_sendkeys(buf, "gg0")
1067  call VerifyScreenDump(buf, 'Test_diff_with_cul_bri_01', {})
1068  call term_sendkeys(buf, "j")
1069  call VerifyScreenDump(buf, 'Test_diff_with_cul_bri_02', {})
1070  call term_sendkeys(buf, "j")
1071  call VerifyScreenDump(buf, 'Test_diff_with_cul_bri_03', {})
1072  call term_sendkeys(buf, "j")
1073  call VerifyScreenDump(buf, 'Test_diff_with_cul_bri_04', {})
1074
1075  " clean up
1076  call StopVimInTerminal(buf)
1077  call delete('Xtest_diff_cursorline_breakindent')
1078endfunc
1079
1080func Test_diff_with_syntax()
1081  CheckScreendump
1082
1083  let lines =<< trim END
1084  	void doNothing() {
1085	   int x = 0;
1086	   char *s = "hello";
1087	   return 5;
1088	}
1089  END
1090  call writefile(lines, 'Xprogram1.c')
1091  let lines =<< trim END
1092  	void doSomething() {
1093	   int x = 0;
1094	   char *s = "there";
1095	   return 5;
1096	}
1097  END
1098  call writefile(lines, 'Xprogram2.c')
1099
1100  let lines =<< trim END
1101  	edit Xprogram1.c
1102	diffsplit Xprogram2.c
1103  END
1104  call writefile(lines, 'Xtest_diff_syntax')
1105  let buf = RunVimInTerminal('-S Xtest_diff_syntax', {})
1106
1107  call VerifyScreenDump(buf, 'Test_diff_syntax_1', {})
1108
1109  " clean up
1110  call StopVimInTerminal(buf)
1111  call delete('Xtest_diff_syntax')
1112  call delete('Xprogram1.c')
1113  call delete('Xprogram2.c')
1114endfunc
1115
1116func Test_diff_of_diff()
1117  CheckScreendump
1118  CheckFeature rightleft
1119
1120  call writefile([
1121	\ 'call setline(1, ["aa","bb","cc","@@ -3,2 +5,7 @@","dd","ee","ff"])',
1122	\ 'vnew',
1123	\ 'call setline(1, ["aa","bb","cc"])',
1124	\ 'windo diffthis',
1125	\ '1wincmd w',
1126	\ 'setlocal number',
1127	\ ], 'Xtest_diff_diff')
1128  let buf = RunVimInTerminal('-S Xtest_diff_diff', {})
1129
1130  call VerifyScreenDump(buf, 'Test_diff_of_diff_01', {})
1131
1132  call term_sendkeys(buf, ":set rightleft\<cr>")
1133  call VerifyScreenDump(buf, 'Test_diff_of_diff_02', {})
1134
1135  " clean up
1136  call StopVimInTerminal(buf)
1137  call delete('Xtest_diff_diff')
1138endfunc
1139
1140func CloseoffSetup()
1141  enew
1142  call setline(1, ['one', 'two', 'three'])
1143  diffthis
1144  new
1145  call setline(1, ['one', 'tow', 'three'])
1146  diffthis
1147  call assert_equal(1, &diff)
1148  only!
1149endfunc
1150
1151func Test_diff_closeoff()
1152  " "closeoff" included by default: last diff win gets 'diff' reset'
1153  call CloseoffSetup()
1154  call assert_equal(0, &diff)
1155  enew!
1156
1157  " "closeoff" excluded: last diff win keeps 'diff' set'
1158  set diffopt-=closeoff
1159  call CloseoffSetup()
1160  call assert_equal(1, &diff)
1161  diffoff!
1162  enew!
1163endfunc
1164
1165func Test_diff_followwrap()
1166  new
1167  set diffopt+=followwrap
1168  set wrap
1169  diffthis
1170  call assert_equal(1, &wrap)
1171  diffoff
1172  set nowrap
1173  diffthis
1174  call assert_equal(0, &wrap)
1175  diffoff
1176  set diffopt&
1177  bwipe!
1178endfunc
1179
1180func Test_diff_maintains_change_mark()
1181  enew!
1182  call setline(1, ['a', 'b', 'c', 'd'])
1183  diffthis
1184  new
1185  call setline(1, ['a', 'b', 'c', 'e'])
1186  " Set '[ and '] marks
1187  2,3yank
1188  call assert_equal([2, 3], [line("'["), line("']")])
1189  " Verify they aren't affected by the implicit diff
1190  diffthis
1191  call assert_equal([2, 3], [line("'["), line("']")])
1192  " Verify they aren't affected by an explicit diff
1193  diffupdate
1194  call assert_equal([2, 3], [line("'["), line("']")])
1195  bwipe!
1196  bwipe!
1197endfunc
1198
1199" Test for 'patchexpr'
1200func Test_patchexpr()
1201  let g:patch_args = []
1202  func TPatch()
1203    call add(g:patch_args, readfile(v:fname_in))
1204    call add(g:patch_args, readfile(v:fname_diff))
1205    call writefile(['output file'], v:fname_out)
1206  endfunc
1207  set patchexpr=TPatch()
1208
1209  call writefile(['input file'], 'Xinput')
1210  call writefile(['diff file'], 'Xdiff')
1211  %bwipe!
1212  edit Xinput
1213  diffpatch Xdiff
1214  call assert_equal('output file', getline(1))
1215  call assert_equal('Xinput.new', bufname())
1216  call assert_equal(2, winnr('$'))
1217  call assert_true(&diff)
1218
1219  call delete('Xinput')
1220  call delete('Xdiff')
1221  set patchexpr&
1222  delfunc TPatch
1223  %bwipe!
1224endfunc
1225
1226func Test_diff_rnu()
1227  CheckScreendump
1228
1229  let content =<< trim END
1230    call setline(1, ['a', 'a', 'a', 'y', 'b', 'b', 'b', 'b', 'b'])
1231    vnew
1232    call setline(1, ['a', 'a', 'a', 'x', 'x', 'x', 'b', 'b', 'b', 'b', 'b'])
1233    windo diffthis
1234    setlocal number rnu foldcolumn=0
1235  END
1236  call writefile(content, 'Xtest_diff_rnu')
1237  let buf = RunVimInTerminal('-S Xtest_diff_rnu', {})
1238
1239  call VerifyScreenDump(buf, 'Test_diff_rnu_01', {})
1240
1241  call term_sendkeys(buf, "j")
1242  call VerifyScreenDump(buf, 'Test_diff_rnu_02', {})
1243  call term_sendkeys(buf, "j")
1244  call VerifyScreenDump(buf, 'Test_diff_rnu_03', {})
1245
1246  " clean up
1247  call StopVimInTerminal(buf)
1248  call delete('Xtest_diff_rnu')
1249endfunc
1250
1251func Test_diff_multilineconceal()
1252  new
1253  diffthis
1254
1255  new
1256  call matchadd('Conceal', 'a\nb', 9, -1, {'conceal': 'Y'})
1257  set cole=2 cocu=n
1258  call setline(1, ["a", "b"])
1259  diffthis
1260  redraw
1261endfunc
1262
1263func Test_diff_and_scroll()
1264  " this was causing an ml_get error
1265  set ls=2
1266  for i in range(winheight(0) * 2)
1267    call setline(i, i < winheight(0) - 10 ? i : i + 10)
1268  endfor
1269  vnew
1270  for i in range(winheight(0)*2 + 10)
1271    call setline(i, i < winheight(0) - 10 ? 0 : i)
1272  endfor
1273  diffthis
1274  wincmd p
1275  diffthis
1276  execute 'normal ' . winheight(0) . "\<C-d>"
1277
1278  bwipe!
1279  bwipe!
1280  set ls&
1281endfunc
1282
1283func Test_diff_filler_cursorcolumn()
1284  CheckScreendump
1285
1286  let content =<< trim END
1287    call setline(1, ['aa', 'bb', 'cc'])
1288    vnew
1289    call setline(1, ['aa', 'cc'])
1290    windo diffthis
1291    wincmd p
1292    setlocal cursorcolumn foldcolumn=0
1293    norm! gg0
1294    redraw!
1295  END
1296  call writefile(content, 'Xtest_diff_cuc')
1297  let buf = RunVimInTerminal('-S Xtest_diff_cuc', {})
1298
1299  call VerifyScreenDump(buf, 'Test_diff_cuc_01', {})
1300
1301  call term_sendkeys(buf, "l")
1302  call term_sendkeys(buf, "\<C-l>")
1303  call VerifyScreenDump(buf, 'Test_diff_cuc_02', {})
1304  call term_sendkeys(buf, "0j")
1305  call term_sendkeys(buf, "\<C-l>")
1306  call VerifyScreenDump(buf, 'Test_diff_cuc_03', {})
1307  call term_sendkeys(buf, "l")
1308  call term_sendkeys(buf, "\<C-l>")
1309  call VerifyScreenDump(buf, 'Test_diff_cuc_04', {})
1310
1311  " clean up
1312  call StopVimInTerminal(buf)
1313  call delete('Xtest_diff_cuc')
1314endfunc
1315
1316" Test for adding/removing lines inside diff chunks, between diff chunks
1317" and before diff chunks
1318func Test_diff_modify_chunks()
1319  enew!
1320  let w2_id = win_getid()
1321  call setline(1, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'])
1322  new
1323  let w1_id = win_getid()
1324  call setline(1, ['a', '2', '3', 'd', 'e', 'f', '7', '8', 'i'])
1325  windo diffthis
1326
1327  " remove a line between two diff chunks and create a new diff chunk
1328  call win_gotoid(w2_id)
1329  5d
1330  call win_gotoid(w1_id)
1331  call diff_hlID(5, 1)->synIDattr('name')->assert_equal('DiffAdd')
1332
1333  " add a line between two diff chunks
1334  call win_gotoid(w2_id)
1335  normal! 4Goe
1336  call win_gotoid(w1_id)
1337  call diff_hlID(4, 1)->synIDattr('name')->assert_equal('')
1338  call diff_hlID(5, 1)->synIDattr('name')->assert_equal('')
1339
1340  " remove all the lines in a diff chunk.
1341  call win_gotoid(w2_id)
1342  7,8d
1343  call win_gotoid(w1_id)
1344  let hl = range(1, 9)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')})
1345  call assert_equal(['', 'DiffText', 'DiffText', '', '', '', 'DiffAdd',
1346        \ 'DiffAdd', ''], hl)
1347
1348  " remove lines from one diff chunk to just before the next diff chunk
1349  call win_gotoid(w2_id)
1350  call setline(1, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'])
1351  2,6d
1352  call win_gotoid(w1_id)
1353  let hl = range(1, 9)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')})
1354  call assert_equal(['', 'DiffText', 'DiffText', 'DiffAdd', 'DiffAdd',
1355        \ 'DiffAdd', 'DiffAdd', 'DiffAdd', ''], hl)
1356
1357  " remove lines just before the top of a diff chunk
1358  call win_gotoid(w2_id)
1359  call setline(1, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'])
1360  5,6d
1361  call win_gotoid(w1_id)
1362  let hl = range(1, 9)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')})
1363  call assert_equal(['', 'DiffText', 'DiffText', '', 'DiffText', 'DiffText',
1364        \ 'DiffAdd', 'DiffAdd', ''], hl)
1365
1366  " remove line after the end of a diff chunk
1367  call win_gotoid(w2_id)
1368  call setline(1, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'])
1369  4d
1370  call win_gotoid(w1_id)
1371  let hl = range(1, 9)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')})
1372  call assert_equal(['', 'DiffText', 'DiffText', 'DiffAdd', '', '', 'DiffText',
1373        \ 'DiffText', ''], hl)
1374
1375  " remove lines starting from the end of one diff chunk and ending inside
1376  " another diff chunk
1377  call win_gotoid(w2_id)
1378  call setline(1, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'])
1379  4,7d
1380  call win_gotoid(w1_id)
1381  let hl = range(1, 9)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')})
1382  call assert_equal(['', 'DiffText', 'DiffText', 'DiffText', 'DiffAdd',
1383        \ 'DiffAdd', 'DiffAdd', 'DiffAdd', ''], hl)
1384
1385  " removing the only remaining diff chunk should make the files equal
1386  call win_gotoid(w2_id)
1387  call setline(1, ['a', '2', '3', 'x', 'd', 'e', 'f', 'x', '7', '8', 'i'])
1388  8d
1389  let hl = range(1, 10)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')})
1390  call assert_equal(['', '', '', 'DiffAdd', '', '', '', '', '', ''], hl)
1391  call win_gotoid(w2_id)
1392  4d
1393  call win_gotoid(w1_id)
1394  let hl = range(1, 9)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')})
1395  call assert_equal(['', '', '', '', '', '', '', '', ''], hl)
1396
1397  %bw!
1398endfunc
1399
1400" vim: shiftwidth=2 sts=2 expandtab
1401