blob: 7e117a3b6662f89a07a3b1ba391af5595fa2de21 [file] [log] [blame]
Bram Moolenaar42093c02016-07-30 16:16:54 +02001" Tests for diff mode
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002
Bram Moolenaare828b762018-09-10 17:51:58 +02003source shared.vim
4source screendump.vim
Bram Moolenaar3c8ee622019-08-03 22:55:50 +02005source check.vim
zeertzjq9e7f1fc2024-03-16 09:40:22 +01006source view_util.vim
Bram Moolenaar42093c02016-07-30 16:16:54 +02007
8func Test_diff_fold_sync()
9 enew!
Bram Moolenaare8fa05b2018-09-16 15:48:06 +020010 let g:update_count = 0
11 au DiffUpdated * let g:update_count += 1
12
Bram Moolenaar42093c02016-07-30 16:16:54 +020013 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
Bram Moolenaarf65cc662022-06-26 18:17:50 +010038 " depending on how redraw is done DiffUpdated may be triggered once or twice
39 call assert_inrange(1, 2, g:update_count)
Bram Moolenaare8fa05b2018-09-16 15:48:06 +020040 au! DiffUpdated
41
Bram Moolenaar42093c02016-07-30 16:16:54 +020042 windo diffoff
43 close!
44 set nomodified
45endfunc
46
47func Test_vert_split()
Bram Moolenaare828b762018-09-10 17:51:58 +020048 set diffopt=filler
49 call Common_vert_split()
50 set diffopt&
51endfunc
52
53func Test_vert_split_internal()
54 set diffopt=internal,filler
55 call Common_vert_split()
56 set diffopt&
57endfunc
58
59func Common_vert_split()
Bram Moolenaar42093c02016-07-30 16:16:54 +020060 " Disable the title to avoid xterm keeping the wrong one.
61 set notitle noicon
62 new
63 let l = ['1 aa', '2 bb', '3 cc', '4 dd', '5 ee']
64 call setline(1, l)
65 w! Xtest
66 normal dd
67 $
68 put
69 normal kkrXoxxx
70 w! Xtest2
71 file Nop
72 normal ggoyyyjjjozzzz
73 set foldmethod=marker foldcolumn=4
74 call assert_equal(0, &diff)
75 call assert_equal('marker', &foldmethod)
76 call assert_equal(4, &foldcolumn)
77 call assert_equal(0, &scrollbind)
78 call assert_equal(0, &cursorbind)
79 call assert_equal(1, &wrap)
80
81 vert diffsplit Xtest
82 vert diffsplit Xtest2
83 call assert_equal(1, &diff)
84 call assert_equal('diff', &foldmethod)
85 call assert_equal(2, &foldcolumn)
86 call assert_equal(1, &scrollbind)
87 call assert_equal(1, &cursorbind)
88 call assert_equal(0, &wrap)
89
90 let diff_fdm = &fdm
91 let diff_fdc = &fdc
92 " repeat entering diff mode here to see if this saves the wrong settings
93 diffthis
94 " jump to second window for a moment to have filler line appear at start of
95 " first window
96 wincmd w
97 normal gg
98 wincmd p
99 normal gg
100 call assert_equal(2, winline())
101 normal j
102 call assert_equal(4, winline())
103 normal j
104 call assert_equal(5, winline())
105 normal j
106 call assert_equal(6, winline())
107 normal j
108 call assert_equal(8, winline())
109 normal j
110 call assert_equal(9, winline())
111
112 wincmd w
113 normal gg
114 call assert_equal(1, winline())
115 normal j
116 call assert_equal(2, winline())
117 normal j
118 call assert_equal(4, winline())
119 normal j
120 call assert_equal(5, winline())
121 normal j
122 call assert_equal(8, winline())
123
124 wincmd w
125 normal gg
126 call assert_equal(2, winline())
127 normal j
128 call assert_equal(3, 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(7, winline())
137 normal j
138 call assert_equal(8, winline())
139
140 " Test diffoff
141 diffoff!
zeertzjq5fd6ab82022-08-17 12:09:45 +0100142 1wincmd w
Bram Moolenaar42093c02016-07-30 16:16:54 +0200143 let &diff = 1
144 let &fdm = diff_fdm
145 let &fdc = diff_fdc
146 4wincmd w
147 diffoff!
148 1wincmd w
149 call assert_equal(0, &diff)
150 call assert_equal('marker', &foldmethod)
151 call assert_equal(4, &foldcolumn)
152 call assert_equal(0, &scrollbind)
153 call assert_equal(0, &cursorbind)
154 call assert_equal(1, &wrap)
155
156 wincmd w
157 call assert_equal(0, &diff)
158 call assert_equal('marker', &foldmethod)
159 call assert_equal(4, &foldcolumn)
160 call assert_equal(0, &scrollbind)
161 call assert_equal(0, &cursorbind)
162 call assert_equal(1, &wrap)
163
164 wincmd w
165 call assert_equal(0, &diff)
166 call assert_equal('marker', &foldmethod)
167 call assert_equal(4, &foldcolumn)
168 call assert_equal(0, &scrollbind)
169 call assert_equal(0, &cursorbind)
170 call assert_equal(1, &wrap)
171
Bram Moolenaar623cf882016-07-30 16:36:01 +0200172 call delete('Xtest')
173 call delete('Xtest2')
Bram Moolenaar42093c02016-07-30 16:16:54 +0200174 windo bw!
175endfunc
176
177func Test_filler_lines()
178 " Test that diffing shows correct filler lines
179 enew!
180 put =range(4,10)
181 1d _
182 vnew
183 put =range(1,10)
184 1d _
185 windo diffthis
186 wincmd h
187 call assert_equal(1, line('w0'))
188 unlet! diff_fdm diff_fdc
Bram Moolenaar90d121f2016-07-30 19:11:25 +0200189 windo diffoff
190 bwipe!
191 enew!
192endfunc
Bram Moolenaar42093c02016-07-30 16:16:54 +0200193
Bram Moolenaar90d121f2016-07-30 19:11:25 +0200194func Test_diffget_diffput()
195 enew!
196 let l = range(50)
197 call setline(1, l)
198 call assert_fails('diffget', 'E99:')
199 diffthis
200 call assert_fails('diffget', 'E100:')
201 new
202 let l[10] = 'one'
203 let l[20] = 'two'
204 let l[30] = 'three'
205 let l[40] = 'four'
206 call setline(1, l)
207 diffthis
208 call assert_equal('one', getline(11))
209 11diffget
210 call assert_equal('10', getline(11))
211 21diffput
212 wincmd w
213 call assert_equal('two', getline(21))
214 normal 31Gdo
215 call assert_equal('three', getline(31))
216 call assert_equal('40', getline(41))
217 normal 41Gdp
218 wincmd w
219 call assert_equal('40', getline(41))
220 new
221 diffthis
222 call assert_fails('diffget', 'E101:')
223
224 windo diffoff
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200225 %bwipe!
226endfunc
227
Bram Moolenaar5f57bdc2018-10-25 17:52:23 +0200228" Test putting two changes from one buffer to another
229func Test_diffput_two()
230 new a
231 let win_a = win_getid()
232 call setline(1, range(1, 10))
233 diffthis
234 new b
235 let win_b = win_getid()
236 call setline(1, range(1, 10))
237 8del
238 5del
239 diffthis
240 call win_gotoid(win_a)
241 %diffput
242 call win_gotoid(win_b)
243 call assert_equal(map(range(1, 10), 'string(v:val)'), getline(1, '$'))
244 bwipe! a
245 bwipe! b
246endfunc
247
Yegappan Lakshmanan30443242021-06-10 21:52:15 +0200248" Test for :diffget/:diffput with a range that is inside a diff chunk
249func Test_diffget_diffput_range()
250 call setline(1, range(1, 10))
251 new
252 call setline(1, range(11, 20))
253 windo diffthis
254 3,5diffget
255 call assert_equal(['13', '14', '15'], getline(3, 5))
256 call setline(1, range(1, 10))
257 4,8diffput
258 wincmd p
259 call assert_equal(['13', '4', '5', '6', '7', '8', '19'], getline(3, 9))
260 %bw!
261endfunc
262
263" Test for :diffget/:diffput with an empty buffer and a non-empty buffer
264func Test_diffget_diffput_empty_buffer()
265 %d _
266 new
267 call setline(1, 'one')
268 windo diffthis
269 diffget
270 call assert_equal(['one'], getline(1, '$'))
271 %d _
272 diffput
273 wincmd p
274 call assert_equal([''], getline(1, '$'))
275 %bw!
276endfunc
277
Bram Moolenaarefcc3292019-12-30 21:59:03 +0100278" :diffput and :diffget completes names of buffers which
Dominique Pelle923dce22021-11-21 11:36:04 +0000279" are in diff mode and which are different than current buffer.
Bram Moolenaarefcc3292019-12-30 21:59:03 +0100280" No completion when the current window is not in diff mode.
Bram Moolenaarae7dba82019-12-29 13:56:33 +0100281func Test_diffget_diffput_completion()
Bram Moolenaarefcc3292019-12-30 21:59:03 +0100282 e Xdiff1 | diffthis
283 botright new Xdiff2
284 botright new Xdiff3 | split | diffthis
285 botright new Xdiff4 | diffthis
Bram Moolenaarae7dba82019-12-29 13:56:33 +0100286
Bram Moolenaarefcc3292019-12-30 21:59:03 +0100287 wincmd t
288 call assert_equal('Xdiff1', bufname('%'))
Bram Moolenaarae7dba82019-12-29 13:56:33 +0100289 call feedkeys(":diffput \<C-A>\<C-B>\"\<CR>", 'tx')
Bram Moolenaarefcc3292019-12-30 21:59:03 +0100290 call assert_equal('"diffput Xdiff3 Xdiff4', @:)
Bram Moolenaarae7dba82019-12-29 13:56:33 +0100291 call feedkeys(":diffget \<C-A>\<C-B>\"\<CR>", 'tx')
Bram Moolenaarefcc3292019-12-30 21:59:03 +0100292 call assert_equal('"diffget Xdiff3 Xdiff4', @:)
293 call assert_equal(['Xdiff3', 'Xdiff4'], getcompletion('', 'diff_buffer'))
Bram Moolenaarae7dba82019-12-29 13:56:33 +0100294
Bram Moolenaarefcc3292019-12-30 21:59:03 +0100295 " Xdiff2 is not in diff mode, so no completion for :diffput, :diffget
296 wincmd j
297 call assert_equal('Xdiff2', bufname('%'))
Bram Moolenaarae7dba82019-12-29 13:56:33 +0100298 call feedkeys(":diffput \<C-A>\<C-B>\"\<CR>", 'tx')
299 call assert_equal('"diffput ', @:)
300 call feedkeys(":diffget \<C-A>\<C-B>\"\<CR>", 'tx')
301 call assert_equal('"diffget ', @:)
302 call assert_equal([], getcompletion('', 'diff_buffer'))
303
Bram Moolenaarefcc3292019-12-30 21:59:03 +0100304 " Xdiff3 is split in 2 windows, only the top one is in diff mode.
305 " So completion of :diffput :diffget only happens in the top window.
306 wincmd j
307 call assert_equal('Xdiff3', bufname('%'))
308 call assert_equal(1, &diff)
309 call feedkeys(":diffput \<C-A>\<C-B>\"\<CR>", 'tx')
310 call assert_equal('"diffput Xdiff1 Xdiff4', @:)
311 call feedkeys(":diffget \<C-A>\<C-B>\"\<CR>", 'tx')
312 call assert_equal('"diffget Xdiff1 Xdiff4', @:)
313 call assert_equal(['Xdiff1', 'Xdiff4'], getcompletion('', 'diff_buffer'))
314
315 wincmd j
316 call assert_equal('Xdiff3', bufname('%'))
317 call assert_equal(0, &diff)
318 call feedkeys(":diffput \<C-A>\<C-B>\"\<CR>", 'tx')
319 call assert_equal('"diffput ', @:)
320 call feedkeys(":diffget \<C-A>\<C-B>\"\<CR>", 'tx')
321 call assert_equal('"diffget ', @:)
322 call assert_equal([], getcompletion('', 'diff_buffer'))
323
324 wincmd j
325 call assert_equal('Xdiff4', bufname('%'))
326 call feedkeys(":diffput \<C-A>\<C-B>\"\<CR>", 'tx')
327 call assert_equal('"diffput Xdiff1 Xdiff3', @:)
328 call feedkeys(":diffget \<C-A>\<C-B>\"\<CR>", 'tx')
329 call assert_equal('"diffget Xdiff1 Xdiff3', @:)
330 call assert_equal(['Xdiff1', 'Xdiff3'], getcompletion('', 'diff_buffer'))
331
Bram Moolenaarae7dba82019-12-29 13:56:33 +0100332 %bwipe
333endfunc
334
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200335func Test_dp_do_buffer()
336 e! one
337 let bn1=bufnr('%')
338 let l = range(60)
339 call setline(1, l)
340 diffthis
341
342 new two
343 let l[10] = 'one'
344 let l[20] = 'two'
345 let l[30] = 'three'
346 let l[40] = 'four'
347 let l[50] = 'five'
348 call setline(1, l)
349 diffthis
350
351 " dp and do with invalid buffer number.
352 11
353 call assert_fails('norm 99999dp', 'E102:')
354 call assert_fails('norm 99999do', 'E102:')
355 call assert_fails('diffput non_existing_buffer', 'E94:')
356 call assert_fails('diffget non_existing_buffer', 'E94:')
357
358 " dp and do with valid buffer number.
359 call assert_equal('one', getline('.'))
360 exe 'norm ' . bn1 . 'do'
361 call assert_equal('10', getline('.'))
362 21
363 call assert_equal('two', getline('.'))
Bram Moolenaar94722c52023-01-28 19:19:03 +0000364 diffget one
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200365 call assert_equal('20', getline('.'))
366
367 31
368 exe 'norm ' . bn1 . 'dp'
369 41
370 diffput one
371 wincmd w
372 31
373 call assert_equal('three', getline('.'))
374 41
375 call assert_equal('four', getline('.'))
376
377 " dp and do with buffer number which is not in diff mode.
378 new not_in_diff_mode
379 let bn3=bufnr('%')
380 wincmd w
381 51
382 call assert_fails('exe "norm" . bn3 . "dp"', 'E103:')
383 call assert_fails('exe "norm" . bn3 . "do"', 'E103:')
384 call assert_fails('diffput not_in_diff_mode', 'E94:')
385 call assert_fails('diffget not_in_diff_mode', 'E94:')
386
387 windo diffoff
388 %bwipe!
Bram Moolenaar42093c02016-07-30 16:16:54 +0200389endfunc
Bram Moolenaare67d5462016-08-27 22:40:42 +0200390
Bram Moolenaardf77cef2018-10-07 17:46:42 +0200391func Test_do_lastline()
392 e! one
393 call setline(1, ['1','2','3','4','5','6'])
394 diffthis
395
396 new two
397 call setline(1, ['2','4','5'])
398 diffthis
399
400 1
401 norm dp]c
402 norm dp]c
403 wincmd w
404 call assert_equal(4, line('$'))
405 norm G
406 norm do
407 call assert_equal(3, line('$'))
408
409 windo diffoff
410 %bwipe!
411endfunc
412
Bram Moolenaare67d5462016-08-27 22:40:42 +0200413func Test_diffoff()
414 enew!
415 call setline(1, ['Two', 'Three'])
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200416 redraw
Bram Moolenaare67d5462016-08-27 22:40:42 +0200417 let normattr = screenattr(1, 1)
418 diffthis
419 botright vert new
420 call setline(1, ['One', '', 'Two', 'Three'])
421 diffthis
422 redraw
Bram Moolenaar196b4662019-09-06 21:34:30 +0200423 call assert_notequal(normattr, 1->screenattr(1))
Bram Moolenaare67d5462016-08-27 22:40:42 +0200424 diffoff!
425 redraw
426 call assert_equal(normattr, screenattr(1, 1))
427 bwipe!
428 bwipe!
429endfunc
Bram Moolenaar025e3e02016-10-18 14:50:18 +0200430
Bram Moolenaare828b762018-09-10 17:51:58 +0200431func Common_icase_test()
432 edit one
Bram Moolenaarda22b8c2017-09-02 18:01:50 +0200433 call setline(1, ['One', 'Two', 'Three', 'Four', 'Fi#ve'])
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200434 redraw
435 let normattr = screenattr(1, 1)
436 diffthis
437
438 botright vert new two
Bram Moolenaarda22b8c2017-09-02 18:01:50 +0200439 call setline(1, ['one', 'TWO', 'Three ', 'Four', 'fI=VE'])
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200440 diffthis
441
442 redraw
443 call assert_equal(normattr, screenattr(1, 1))
444 call assert_equal(normattr, screenattr(2, 1))
445 call assert_notequal(normattr, screenattr(3, 1))
446 call assert_equal(normattr, screenattr(4, 1))
447
Bram Moolenaarda22b8c2017-09-02 18:01:50 +0200448 let dtextattr = screenattr(5, 3)
449 call assert_notequal(dtextattr, screenattr(5, 1))
450 call assert_notequal(dtextattr, screenattr(5, 5))
451
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200452 diffoff!
453 %bwipe!
Bram Moolenaare828b762018-09-10 17:51:58 +0200454endfunc
455
456func Test_diffopt_icase()
457 set diffopt=icase,foldcolumn:0
458 call Common_icase_test()
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200459 set diffopt&
460endfunc
461
Bram Moolenaare828b762018-09-10 17:51:58 +0200462func Test_diffopt_icase_internal()
463 set diffopt=icase,foldcolumn:0,internal
464 call Common_icase_test()
465 set diffopt&
466endfunc
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200467
Bram Moolenaare828b762018-09-10 17:51:58 +0200468func Common_iwhite_test()
469 edit one
470 " Difference in trailing spaces and amount of spaces should be ignored,
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200471 " but not other space differences.
Bram Moolenaare828b762018-09-10 17:51:58 +0200472 call setline(1, ["One \t", 'Two', 'Three', 'one two', 'one two', 'Four'])
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200473 redraw
474 let normattr = screenattr(1, 1)
475 diffthis
476
477 botright vert new two
Bram Moolenaare828b762018-09-10 17:51:58 +0200478 call setline(1, ["One\t ", "Two\t ", 'Three', 'one two', 'onetwo', ' Four'])
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200479 diffthis
480
481 redraw
482 call assert_equal(normattr, screenattr(1, 1))
483 call assert_equal(normattr, screenattr(2, 1))
484 call assert_equal(normattr, screenattr(3, 1))
Bram Moolenaare828b762018-09-10 17:51:58 +0200485 call assert_equal(normattr, screenattr(4, 1))
486 call assert_notequal(normattr, screenattr(5, 1))
487 call assert_notequal(normattr, screenattr(6, 1))
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200488
489 diffoff!
490 %bwipe!
Bram Moolenaare828b762018-09-10 17:51:58 +0200491endfunc
492
493func Test_diffopt_iwhite()
494 set diffopt=iwhite,foldcolumn:0
495 call Common_iwhite_test()
496 set diffopt&
497endfunc
498
499func Test_diffopt_iwhite_internal()
500 set diffopt=internal,iwhite,foldcolumn:0
501 call Common_iwhite_test()
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200502 set diffopt&
503endfunc
504
505func Test_diffopt_context()
506 enew!
507 call setline(1, ['1', '2', '3', '4', '5', '6', '7'])
508 diffthis
509 new
510 call setline(1, ['1', '2', '3', '4', '5x', '6', '7'])
511 diffthis
512
513 set diffopt=context:2
514 call assert_equal('+-- 2 lines: 1', foldtextresult(1))
Bram Moolenaare828b762018-09-10 17:51:58 +0200515 set diffopt=internal,context:2
516 call assert_equal('+-- 2 lines: 1', foldtextresult(1))
517
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200518 set diffopt=context:1
519 call assert_equal('+-- 3 lines: 1', foldtextresult(1))
Bram Moolenaare828b762018-09-10 17:51:58 +0200520 set diffopt=internal,context:1
521 call assert_equal('+-- 3 lines: 1', foldtextresult(1))
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200522
523 diffoff!
524 %bwipe!
525 set diffopt&
526endfunc
527
528func Test_diffopt_horizontal()
Bram Moolenaare828b762018-09-10 17:51:58 +0200529 set diffopt=internal,horizontal
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200530 diffsplit
531
532 call assert_equal(&columns, winwidth(1))
533 call assert_equal(&columns, winwidth(2))
534 call assert_equal(&lines, winheight(1) + winheight(2) + 3)
535 call assert_inrange(0, 1, winheight(1) - winheight(2))
536
537 set diffopt&
538 diffoff!
539 %bwipe
540endfunc
541
542func Test_diffopt_vertical()
Bram Moolenaare828b762018-09-10 17:51:58 +0200543 set diffopt=internal,vertical
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200544 diffsplit
545
546 call assert_equal(&lines - 2, winheight(1))
547 call assert_equal(&lines - 2, winheight(2))
548 call assert_equal(&columns, winwidth(1) + winwidth(2) + 1)
549 call assert_inrange(0, 1, winwidth(1) - winwidth(2))
550
551 set diffopt&
552 diffoff!
553 %bwipe
554endfunc
555
Bram Moolenaar97ce4192017-12-01 20:35:58 +0100556func Test_diffopt_hiddenoff()
Bram Moolenaare828b762018-09-10 17:51:58 +0200557 set diffopt=internal,filler,foldcolumn:0,hiddenoff
Bram Moolenaar97ce4192017-12-01 20:35:58 +0100558 e! one
559 call setline(1, ['Two', 'Three'])
560 redraw
561 let normattr = screenattr(1, 1)
562 diffthis
563 botright vert new two
564 call setline(1, ['One', 'Four'])
565 diffthis
566 redraw
567 call assert_notequal(normattr, screenattr(1, 1))
568 set hidden
569 close
570 redraw
571 " should not diffing with hidden buffer two while 'hiddenoff' is enabled
572 call assert_equal(normattr, screenattr(1, 1))
573
574 bwipe!
575 bwipe!
576 set hidden& diffopt&
577endfunc
578
Bram Moolenaar25ea0542017-02-03 23:16:28 +0100579func Test_diffoff_hidden()
Bram Moolenaare828b762018-09-10 17:51:58 +0200580 set diffopt=internal,filler,foldcolumn:0
Bram Moolenaar25ea0542017-02-03 23:16:28 +0100581 e! one
582 call setline(1, ['Two', 'Three'])
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200583 redraw
Bram Moolenaar25ea0542017-02-03 23:16:28 +0100584 let normattr = screenattr(1, 1)
585 diffthis
586 botright vert new two
587 call setline(1, ['One', 'Four'])
588 diffthis
589 redraw
590 call assert_notequal(normattr, screenattr(1, 1))
591 set hidden
592 close
593 redraw
594 " diffing with hidden buffer two
595 call assert_notequal(normattr, screenattr(1, 1))
596 diffoff
597 redraw
598 call assert_equal(normattr, screenattr(1, 1))
599 diffthis
600 redraw
601 " still diffing with hidden buffer two
602 call assert_notequal(normattr, screenattr(1, 1))
603 diffoff!
604 redraw
605 call assert_equal(normattr, screenattr(1, 1))
606 diffthis
607 redraw
608 " no longer diffing with hidden buffer two
609 call assert_equal(normattr, screenattr(1, 1))
610
611 bwipe!
612 bwipe!
613 set hidden& diffopt&
614endfunc
615
Bram Moolenaar025e3e02016-10-18 14:50:18 +0200616func Test_setting_cursor()
617 new Xtest1
618 put =range(1,90)
619 wq
620 new Xtest2
621 put =range(1,100)
622 wq
Bram Moolenaar97fbc402017-09-26 19:41:46 +0200623
Bram Moolenaar025e3e02016-10-18 14:50:18 +0200624 tabe Xtest2
625 $
626 diffsp Xtest1
627 tabclose
628
629 call delete('Xtest1')
630 call delete('Xtest2')
631endfunc
Bram Moolenaaraeb661e2017-02-26 19:59:59 +0100632
633func Test_diff_move_to()
634 new
635 call setline(1, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
636 diffthis
637 vnew
638 call setline(1, [1, '2x', 3, 4, 4, 5, '6x', 7, '8x', 9, '10x'])
639 diffthis
640 norm ]c
641 call assert_equal(2, line('.'))
642 norm 3]c
643 call assert_equal(9, line('.'))
644 norm 10]c
645 call assert_equal(11, line('.'))
646 norm [c
647 call assert_equal(9, line('.'))
648 norm 2[c
649 call assert_equal(5, line('.'))
650 norm 10[c
651 call assert_equal(2, line('.'))
652 %bwipe!
653endfunc
654
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200655func Test_diffexpr()
Bram Moolenaaraeb313f2020-11-27 19:13:28 +0100656 CheckExecutable diff
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200657
658 func DiffExpr()
Bram Moolenaar485b6272021-05-18 19:19:03 +0200659 " Prepend some text to check diff type detection
Bram Moolenaar3b8defd2018-09-13 13:03:11 +0200660 call writefile(['warning', ' message'], v:fname_out)
661 silent exe '!diff ' . v:fname_in . ' ' . v:fname_new . '>>' . v:fname_out
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200662 endfunc
663 set diffexpr=DiffExpr()
664 set diffopt=foldcolumn:0
665
666 enew!
667 call setline(1, ['one', 'two', 'three'])
668 redraw
669 let normattr = screenattr(1, 1)
670 diffthis
671
672 botright vert new
673 call setline(1, ['one', 'two', 'three.'])
674 diffthis
675
676 redraw
677 call assert_equal(normattr, screenattr(1, 1))
678 call assert_equal(normattr, screenattr(2, 1))
679 call assert_notequal(normattr, screenattr(3, 1))
Yegappan Lakshmanan30443242021-06-10 21:52:15 +0200680 diffoff!
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200681
Dominique Pelle923dce22021-11-21 11:36:04 +0000682 " Try using a non-existing function for 'diffexpr'.
Yegappan Lakshmanan30443242021-06-10 21:52:15 +0200683 set diffexpr=NewDiffFunc()
684 call assert_fails('windo diffthis', ['E117:', 'E97:'])
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200685 diffoff!
Yegappan Lakshmanan8bb65f22021-12-26 10:51:39 +0000686
687 " Using a script-local function
688 func s:NewDiffExpr()
689 endfunc
690 set diffexpr=s:NewDiffExpr()
691 call assert_equal(expand('<SID>') .. 'NewDiffExpr()', &diffexpr)
692 set diffexpr=<SID>NewDiffExpr()
693 call assert_equal(expand('<SID>') .. 'NewDiffExpr()', &diffexpr)
694
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200695 %bwipe!
696 set diffexpr& diffopt&
Yegappan Lakshmanan8bb65f22021-12-26 10:51:39 +0000697 delfunc DiffExpr
698 delfunc s:NewDiffExpr
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200699endfunc
700
Bram Moolenaaraeb661e2017-02-26 19:59:59 +0100701func Test_diffpatch()
702 " The patch program on MS-Windows may fail or hang.
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200703 CheckExecutable patch
704 CheckUnix
Bram Moolenaaraeb661e2017-02-26 19:59:59 +0100705 new
706 insert
707***************
708*** 1,3 ****
709 1
710! 2
711 3
712--- 1,4 ----
713 1
714! 2x
715 3
716+ 4
717.
Bram Moolenaar97fbc402017-09-26 19:41:46 +0200718 saveas! Xpatch
Bram Moolenaaraeb661e2017-02-26 19:59:59 +0100719 bwipe!
720 new
721 call assert_fails('diffpatch Xpatch', 'E816:')
Bram Moolenaar1ef73e32017-03-09 19:21:30 +0100722
Bram Moolenaara95ab322017-03-11 19:21:53 +0100723 for name in ['Xpatch', 'Xpatch$HOME', 'Xpa''tch']
Bram Moolenaar1ef73e32017-03-09 19:21:30 +0100724 call setline(1, ['1', '2', '3'])
725 if name != 'Xpatch'
726 call rename('Xpatch', name)
727 endif
728 exe 'diffpatch ' . escape(name, '$')
729 call assert_equal(['1', '2x', '3', '4'], getline(1, '$'))
730 if name != 'Xpatch'
731 call rename(name, 'Xpatch')
732 endif
733 bwipe!
734 endfor
735
Bram Moolenaaraeb661e2017-02-26 19:59:59 +0100736 call delete('Xpatch')
737 bwipe!
738endfunc
739
Bram Moolenaar23a971d2023-04-04 22:04:53 +0100740" FIXME: test fails, the Xresult file can't be read
741func No_Test_diffpatch_restricted()
742 let lines =<< trim END
743 call assert_fails('diffpatch NoSuchDiff', 'E145:')
744
745 call writefile(v:errors, 'Xresult')
746 qa!
747 END
748 call writefile(lines, 'Xrestricted', 'D')
749 if RunVim([], [], '-Z --clean -S Xrestricted')
750 call assert_equal([], readfile('Xresult'))
751 endif
752 call delete('Xresult')
753endfunc
754
Bram Moolenaaraeb661e2017-02-26 19:59:59 +0100755func Test_diff_too_many_buffers()
756 for i in range(1, 8)
757 exe "new Xtest" . i
758 diffthis
759 endfor
760 new Xtest9
761 call assert_fails('diffthis', 'E96:')
762 %bwipe!
763endfunc
764
765func Test_diff_nomodifiable()
766 new
767 call setline(1, [1, 2, 3, 4])
768 setl nomodifiable
769 diffthis
770 vnew
771 call setline(1, ['1x', 2, 3, 3, 4])
772 diffthis
773 call assert_fails('norm dp', 'E793:')
774 setl nomodifiable
775 call assert_fails('norm do', 'E21:')
776 %bwipe!
777endfunc
Bram Moolenaarf58a8472017-03-05 18:03:04 +0100778
Bram Moolenaar97fbc402017-09-26 19:41:46 +0200779func Test_diff_hlID()
780 new
781 call setline(1, [1, 2, 3])
782 diffthis
783 vnew
784 call setline(1, ['1x', 2, 'x', 3])
785 diffthis
786 redraw
787
Bram Moolenaara74e4942019-08-04 17:35:53 +0200788 call diff_hlID(-1, 1)->synIDattr("name")->assert_equal("")
Bram Moolenaar97fbc402017-09-26 19:41:46 +0200789
Bram Moolenaara74e4942019-08-04 17:35:53 +0200790 call diff_hlID(1, 1)->synIDattr("name")->assert_equal("DiffChange")
791 call diff_hlID(1, 2)->synIDattr("name")->assert_equal("DiffText")
792 call diff_hlID(2, 1)->synIDattr("name")->assert_equal("")
793 call diff_hlID(3, 1)->synIDattr("name")->assert_equal("DiffAdd")
Bram Moolenaar1a3a8912019-08-23 22:31:37 +0200794 eval 4->diff_hlID(1)->synIDattr("name")->assert_equal("")
Bram Moolenaar97fbc402017-09-26 19:41:46 +0200795
796 wincmd w
797 call assert_equal(synIDattr(diff_hlID(1, 1), "name"), "DiffChange")
798 call assert_equal(synIDattr(diff_hlID(2, 1), "name"), "")
799 call assert_equal(synIDattr(diff_hlID(3, 1), "name"), "")
800
801 %bwipe!
802endfunc
803
804func Test_diff_filler()
805 new
806 call setline(1, [1, 2, 3, 'x', 4])
807 diffthis
808 vnew
809 call setline(1, [1, 2, 'y', 'y', 3, 4])
810 diffthis
811 redraw
812
Bram Moolenaar1a3a8912019-08-23 22:31:37 +0200813 call assert_equal([0, 0, 0, 0, 0, 0, 0, 1, 0], map(range(-1, 7), 'v:val->diff_filler()'))
Bram Moolenaar97fbc402017-09-26 19:41:46 +0200814 wincmd w
815 call assert_equal([0, 0, 0, 0, 2, 0, 0, 0], map(range(-1, 6), 'diff_filler(v:val)'))
816
817 %bwipe!
818endfunc
819
Bram Moolenaarf58a8472017-03-05 18:03:04 +0100820func Test_diff_lastline()
821 enew!
822 only!
823 call setline(1, ['This is a ', 'line with five ', 'rows'])
824 diffthis
825 botright vert new
826 call setline(1, ['This is', 'a line with ', 'four rows'])
827 diffthis
828 1
829 call feedkeys("Je a\<CR>", 'tx')
830 call feedkeys("Je a\<CR>", 'tx')
831 let w1lines = winline()
832 wincmd w
833 $
834 let w2lines = winline()
835 call assert_equal(w2lines, w1lines)
836 bwipe!
837 bwipe!
838endfunc
Bram Moolenaare828b762018-09-10 17:51:58 +0200839
Bram Moolenaar785fc652018-09-15 19:17:38 +0200840func WriteDiffFiles(buf, list1, list2)
Bram Moolenaar61abe7d2022-08-30 21:46:08 +0100841 call writefile(a:list1, 'Xdifile1')
842 call writefile(a:list2, 'Xdifile2')
Bram Moolenaar785fc652018-09-15 19:17:38 +0200843 if a:buf
844 call term_sendkeys(a:buf, ":checktime\<CR>")
845 endif
Bram Moolenaare828b762018-09-10 17:51:58 +0200846endfunc
847
Yukihiro Nakadaira06fe70c2024-09-26 16:19:42 +0200848func WriteDiffFiles3(buf, list1, list2, list3)
849 call writefile(a:list1, 'Xdifile1')
850 call writefile(a:list2, 'Xdifile2')
851 call writefile(a:list3, 'Xdifile3')
852 if a:buf
853 call term_sendkeys(a:buf, ":checktime\<CR>")
854 endif
855endfunc
856
Bram Moolenaar785fc652018-09-15 19:17:38 +0200857" Verify a screendump with both the internal and external diff.
Bram Moolenaare828b762018-09-10 17:51:58 +0200858func VerifyBoth(buf, dumpfile, extra)
Bram Moolenaare828b762018-09-10 17:51:58 +0200859 " trailing : for leaving the cursor on the command line
Bram Moolenaar785fc652018-09-15 19:17:38 +0200860 for cmd in [":set diffopt=filler" . a:extra . "\<CR>:", ":set diffopt+=internal\<CR>:"]
Bram Moolenaare828b762018-09-10 17:51:58 +0200861 call term_sendkeys(a:buf, cmd)
862 if VerifyScreenDump(a:buf, a:dumpfile, {}, cmd =~ 'internal' ? 'internal' : 'external')
Bram Moolenaar485b6272021-05-18 19:19:03 +0200863 " don't let the next iteration overwrite the "failed" file.
864 return
Bram Moolenaare828b762018-09-10 17:51:58 +0200865 endif
866 endfor
Bram Moolenaar485b6272021-05-18 19:19:03 +0200867
868 " also test unified diff
869 call term_sendkeys(a:buf, ":call SetupUnified()\<CR>:")
glacambread5c1782021-05-24 14:20:53 +0200870 call term_sendkeys(a:buf, ":redraw!\<CR>:")
Bram Moolenaar485b6272021-05-18 19:19:03 +0200871 call VerifyScreenDump(a:buf, a:dumpfile, {}, 'unified')
872 call term_sendkeys(a:buf, ":call StopUnified()\<CR>:")
Bram Moolenaare828b762018-09-10 17:51:58 +0200873endfunc
874
Bram Moolenaar785fc652018-09-15 19:17:38 +0200875" Verify a screendump with the internal diff only.
876func VerifyInternal(buf, dumpfile, extra)
877 call term_sendkeys(a:buf, ":diffupdate!\<CR>")
878 " trailing : for leaving the cursor on the command line
879 call term_sendkeys(a:buf, ":set diffopt=internal,filler" . a:extra . "\<CR>:")
880 call VerifyScreenDump(a:buf, a:dumpfile, {})
881endfunc
882
Bram Moolenaare828b762018-09-10 17:51:58 +0200883func Test_diff_screen()
Yee Cheng Chin49f2ba62024-02-14 20:34:58 +0100884 if has('osxdarwin') && system('diff --version') =~ '^Apple diff'
885 throw 'Skipped: unified diff does not work properly on this macOS version'
rhysde93d5ca2024-02-01 21:22:14 +0100886 endif
887
Bram Moolenaarf08b0eb2021-10-16 13:00:14 +0100888 let g:test_is_flaky = 1
Bram Moolenaar3c8ee622019-08-03 22:55:50 +0200889 CheckScreendump
890 CheckFeature menu
891
Bram Moolenaar485b6272021-05-18 19:19:03 +0200892 let lines =<< trim END
893 func UnifiedDiffExpr()
894 " Prepend some text to check diff type detection
895 call writefile(['warning', ' message'], v:fname_out)
glacambread5c1782021-05-24 14:20:53 +0200896 silent exe '!diff -U0 ' .. v:fname_in .. ' ' .. v:fname_new .. '>>' .. v:fname_out
Bram Moolenaar485b6272021-05-18 19:19:03 +0200897 endfunc
898 func SetupUnified()
899 set diffexpr=UnifiedDiffExpr()
glacambread5c1782021-05-24 14:20:53 +0200900 diffupdate
Bram Moolenaar485b6272021-05-18 19:19:03 +0200901 endfunc
902 func StopUnified()
903 set diffexpr=
904 endfunc
905 END
Bram Moolenaar59173412022-09-20 22:01:33 +0100906 call writefile(lines, 'XdiffSetup', 'D')
Bram Moolenaar485b6272021-05-18 19:19:03 +0200907
Bram Moolenaare828b762018-09-10 17:51:58 +0200908 " clean up already existing swap files, just in case
Bram Moolenaar61abe7d2022-08-30 21:46:08 +0100909 call delete('.Xdifile1.swp')
910 call delete('.Xdifile2.swp')
Bram Moolenaare828b762018-09-10 17:51:58 +0200911
912 " Test 1: Add a line in beginning of file 2
Bram Moolenaar785fc652018-09-15 19:17:38 +0200913 call WriteDiffFiles(0, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
Bram Moolenaar61abe7d2022-08-30 21:46:08 +0100914 let buf = RunVimInTerminal('-d -S XdiffSetup Xdifile1 Xdifile2', {})
Bram Moolenaar8ee4c012019-03-29 18:08:18 +0100915 " Set autoread mode, so that Vim won't complain once we re-write the test
Bram Moolenaare828b762018-09-10 17:51:58 +0200916 " files
Bram Moolenaar785fc652018-09-15 19:17:38 +0200917 call term_sendkeys(buf, ":set autoread\<CR>\<c-w>w:set autoread\<CR>\<c-w>w")
Bram Moolenaare828b762018-09-10 17:51:58 +0200918
919 call VerifyBoth(buf, 'Test_diff_01', '')
920
921 " Test 2: Add a line in beginning of file 1
Bram Moolenaar785fc652018-09-15 19:17:38 +0200922 call WriteDiffFiles(buf, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
Bram Moolenaare828b762018-09-10 17:51:58 +0200923 call VerifyBoth(buf, 'Test_diff_02', '')
924
925 " Test 3: Add a line at the end of file 2
Bram Moolenaar785fc652018-09-15 19:17:38 +0200926 call WriteDiffFiles(buf, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
Bram Moolenaare828b762018-09-10 17:51:58 +0200927 call VerifyBoth(buf, 'Test_diff_03', '')
928
929 " Test 4: Add a line at the end of file 1
Bram Moolenaar785fc652018-09-15 19:17:38 +0200930 call WriteDiffFiles(buf, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
Bram Moolenaare828b762018-09-10 17:51:58 +0200931 call VerifyBoth(buf, 'Test_diff_04', '')
932
933 " Test 5: Add a line in the middle of file 2, remove on at the end of file 1
Bram Moolenaar785fc652018-09-15 19:17:38 +0200934 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])
Bram Moolenaare828b762018-09-10 17:51:58 +0200935 call VerifyBoth(buf, 'Test_diff_05', '')
936
937 " Test 6: Add a line in the middle of file 1, remove on at the end of file 2
Bram Moolenaar785fc652018-09-15 19:17:38 +0200938 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])
Bram Moolenaare828b762018-09-10 17:51:58 +0200939 call VerifyBoth(buf, 'Test_diff_06', '')
940
Bram Moolenaarb9ddda62019-02-19 23:00:50 +0100941 " Variants on test 6 with different context settings
942 call term_sendkeys(buf, ":set diffopt+=context:2\<cr>")
943 call VerifyScreenDump(buf, 'Test_diff_06.2', {})
944 call term_sendkeys(buf, ":set diffopt-=context:2\<cr>")
945 call term_sendkeys(buf, ":set diffopt+=context:1\<cr>")
946 call VerifyScreenDump(buf, 'Test_diff_06.1', {})
947 call term_sendkeys(buf, ":set diffopt-=context:1\<cr>")
948 call term_sendkeys(buf, ":set diffopt+=context:0\<cr>")
949 call VerifyScreenDump(buf, 'Test_diff_06.0', {})
950 call term_sendkeys(buf, ":set diffopt-=context:0\<cr>")
951
Bram Moolenaare828b762018-09-10 17:51:58 +0200952 " Test 7 - 9: Test normal/patience/histogram diff algorithm
Bram Moolenaar785fc652018-09-15 19:17:38 +0200953 call WriteDiffFiles(buf, ['#include <stdio.h>', '', '// Frobs foo heartily', 'int frobnitz(int foo)', '{',
Bram Moolenaare828b762018-09-10 17:51:58 +0200954 \ ' int i;', ' for(i = 0; i < 10; i++)', ' {', ' printf("Your answer is: ");',
955 \ ' printf("%d\n", foo);', ' }', '}', '', 'int fact(int n)', '{', ' if(n > 1)', ' {',
956 \ ' return fact(n-1) * n;', ' }', ' return 1;', '}', '', 'int main(int argc, char **argv)',
957 \ '{', ' frobnitz(fact(10));', '}'],
958 \ ['#include <stdio.h>', '', 'int fib(int n)', '{', ' if(n > 2)', ' {',
959 \ ' return fib(n-1) + fib(n-2);', ' }', ' return 1;', '}', '', '// Frobs foo heartily',
960 \ 'int frobnitz(int foo)', '{', ' int i;', ' for(i = 0; i < 10; i++)', ' {',
961 \ ' printf("%d\n", foo);', ' }', '}', '',
962 \ 'int main(int argc, char **argv)', '{', ' frobnitz(fib(10));', '}'])
963 call term_sendkeys(buf, ":diffupdate!\<cr>")
964 call term_sendkeys(buf, ":set diffopt+=internal\<cr>")
965 call VerifyScreenDump(buf, 'Test_diff_07', {})
966
967 call term_sendkeys(buf, ":set diffopt+=algorithm:patience\<cr>")
968 call VerifyScreenDump(buf, 'Test_diff_08', {})
969
970 call term_sendkeys(buf, ":set diffopt+=algorithm:histogram\<cr>")
971 call VerifyScreenDump(buf, 'Test_diff_09', {})
972
973 " Test 10-11: normal/indent-heuristic
974 call term_sendkeys(buf, ":set diffopt&vim\<cr>")
Bram Moolenaar785fc652018-09-15 19:17:38 +0200975 call WriteDiffFiles(buf, ['', ' def finalize(values)', '', ' values.each do |v|', ' v.finalize', ' end'],
Bram Moolenaare828b762018-09-10 17:51:58 +0200976 \ ['', ' def finalize(values)', '', ' values.each do |v|', ' v.prepare', ' end', '',
977 \ ' values.each do |v|', ' v.finalize', ' end'])
978 call term_sendkeys(buf, ":diffupdate!\<cr>")
979 call term_sendkeys(buf, ":set diffopt+=internal\<cr>")
980 call VerifyScreenDump(buf, 'Test_diff_10', {})
981
Bram Moolenaarb6fc7282018-12-04 22:24:16 +0100982 " Leave trailing : at commandline!
983 call term_sendkeys(buf, ":set diffopt+=indent-heuristic\<cr>:\<cr>")
984 call VerifyScreenDump(buf, 'Test_diff_11', {}, 'one')
985 " shouldn't matter, if indent-algorithm comes before or after the algorithm
986 call term_sendkeys(buf, ":set diffopt&\<cr>")
987 call term_sendkeys(buf, ":set diffopt+=indent-heuristic,algorithm:patience\<cr>:\<cr>")
988 call VerifyScreenDump(buf, 'Test_diff_11', {}, 'two')
989 call term_sendkeys(buf, ":set diffopt&\<cr>")
990 call term_sendkeys(buf, ":set diffopt+=algorithm:patience,indent-heuristic\<cr>:\<cr>")
991 call VerifyScreenDump(buf, 'Test_diff_11', {}, 'three')
Bram Moolenaare828b762018-09-10 17:51:58 +0200992
993 " Test 12: diff the same file
Bram Moolenaar785fc652018-09-15 19:17:38 +0200994 call WriteDiffFiles(buf, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
Bram Moolenaare828b762018-09-10 17:51:58 +0200995 call VerifyBoth(buf, 'Test_diff_12', '')
996
997 " Test 13: diff an empty file
Bram Moolenaar785fc652018-09-15 19:17:38 +0200998 call WriteDiffFiles(buf, [], [])
Bram Moolenaare828b762018-09-10 17:51:58 +0200999 call VerifyBoth(buf, 'Test_diff_13', '')
1000
1001 " Test 14: test diffopt+=icase
Bram Moolenaar785fc652018-09-15 19:17:38 +02001002 call WriteDiffFiles(buf, ['a', 'b', 'cd'], ['A', 'b', 'cDe'])
Bram Moolenaare828b762018-09-10 17:51:58 +02001003 call VerifyBoth(buf, 'Test_diff_14', " diffopt+=filler diffopt+=icase")
1004
1005 " Test 15-16: test diffopt+=iwhite
Bram Moolenaar785fc652018-09-15 19:17:38 +02001006 call WriteDiffFiles(buf, ['int main()', '{', ' printf("Hello, World!");', ' return 0;', '}'],
Bram Moolenaare828b762018-09-10 17:51:58 +02001007 \ ['int main()', '{', ' if (0)', ' {', ' printf("Hello, World!");', ' return 0;', ' }', '}'])
1008 call term_sendkeys(buf, ":diffupdate!\<cr>")
1009 call term_sendkeys(buf, ":set diffopt&vim diffopt+=filler diffopt+=iwhite\<cr>")
1010 call VerifyScreenDump(buf, 'Test_diff_15', {})
1011 call term_sendkeys(buf, ":set diffopt+=internal\<cr>")
1012 call VerifyScreenDump(buf, 'Test_diff_16', {})
1013
Bram Moolenaar785fc652018-09-15 19:17:38 +02001014 " Test 17: test diffopt+=iblank
1015 call WriteDiffFiles(buf, ['a', ' ', 'cd', 'ef', 'xxx'], ['a', 'cd', '', 'ef', 'yyy'])
1016 call VerifyInternal(buf, 'Test_diff_17', " diffopt+=iblank")
1017
1018 " Test 18: test diffopt+=iblank,iwhite / iwhiteall / iwhiteeol
1019 call VerifyInternal(buf, 'Test_diff_18', " diffopt+=iblank,iwhite")
1020 call VerifyInternal(buf, 'Test_diff_18', " diffopt+=iblank,iwhiteall")
1021 call VerifyInternal(buf, 'Test_diff_18', " diffopt+=iblank,iwhiteeol")
1022
1023 " Test 19: test diffopt+=iwhiteeol
1024 call WriteDiffFiles(buf, ['a ', 'x', 'cd', 'ef', 'xx xx', 'foo', 'bar'], ['a', 'x', 'c d', ' ef', 'xx xx', 'foo', '', 'bar'])
1025 call VerifyInternal(buf, 'Test_diff_19', " diffopt+=iwhiteeol")
1026
Yukihiro Nakadairaf1694b42024-09-22 11:26:13 +02001027 " Test 20: test diffopt+=iwhiteall
Bram Moolenaar785fc652018-09-15 19:17:38 +02001028 call VerifyInternal(buf, 'Test_diff_20', " diffopt+=iwhiteall")
1029
Yukihiro Nakadairaf1694b42024-09-22 11:26:13 +02001030 " Test 21: Delete all lines
1031 call WriteDiffFiles(buf, [0], [])
1032 call VerifyBoth(buf, "Test_diff_21", "")
1033
1034 " Test 22: Add line to empty file
1035 call WriteDiffFiles(buf, [], [0])
1036 call VerifyBoth(buf, "Test_diff_22", "")
1037
Bram Moolenaare828b762018-09-10 17:51:58 +02001038 " clean up
1039 call StopVimInTerminal(buf)
Bram Moolenaar61abe7d2022-08-30 21:46:08 +01001040 call delete('Xdifile1')
1041 call delete('Xdifile2')
Bram Moolenaare828b762018-09-10 17:51:58 +02001042endfunc
1043
Bram Moolenaar04626c22021-09-01 16:02:07 +02001044func Test_diff_with_scroll_and_change()
1045 CheckScreendump
1046
1047 let lines =<< trim END
1048 call setline(1, range(1, 15))
1049 vnew
1050 call setline(1, range(9, 15))
1051 windo diffthis
1052 wincmd h
1053 exe "normal Gl5\<C-E>"
1054 END
Bram Moolenaar59173412022-09-20 22:01:33 +01001055 call writefile(lines, 'Xtest_scroll_change', 'D')
Bram Moolenaar04626c22021-09-01 16:02:07 +02001056 let buf = RunVimInTerminal('-S Xtest_scroll_change', {})
1057
1058 call VerifyScreenDump(buf, 'Test_diff_scroll_change_01', {})
1059
1060 call term_sendkeys(buf, "ax\<Esc>")
1061 call VerifyScreenDump(buf, 'Test_diff_scroll_change_02', {})
1062
Bram Moolenaar841c2252021-10-22 20:56:55 +01001063 call term_sendkeys(buf, "\<C-W>lay\<Esc>")
1064 call VerifyScreenDump(buf, 'Test_diff_scroll_change_03', {})
1065
Bram Moolenaar04626c22021-09-01 16:02:07 +02001066 " clean up
1067 call StopVimInTerminal(buf)
Bram Moolenaar04626c22021-09-01 16:02:07 +02001068endfunc
1069
Bram Moolenaar4a5abbd2018-10-02 18:26:10 +02001070func Test_diff_with_cursorline()
Bram Moolenaar3c8ee622019-08-03 22:55:50 +02001071 CheckScreendump
Bram Moolenaar4a5abbd2018-10-02 18:26:10 +02001072
1073 call writefile([
1074 \ 'hi CursorLine ctermbg=red ctermfg=white',
1075 \ 'set cursorline',
1076 \ 'call setline(1, ["foo","foo","foo","bar"])',
1077 \ 'vnew',
1078 \ 'call setline(1, ["bee","foo","foo","baz"])',
1079 \ 'windo diffthis',
1080 \ '2wincmd w',
Bram Moolenaar59173412022-09-20 22:01:33 +01001081 \ ], 'Xtest_diff_cursorline', 'D')
Bram Moolenaar4a5abbd2018-10-02 18:26:10 +02001082 let buf = RunVimInTerminal('-S Xtest_diff_cursorline', {})
1083
1084 call VerifyScreenDump(buf, 'Test_diff_with_cursorline_01', {})
1085 call term_sendkeys(buf, "j")
1086 call VerifyScreenDump(buf, 'Test_diff_with_cursorline_02', {})
1087 call term_sendkeys(buf, "j")
1088 call VerifyScreenDump(buf, 'Test_diff_with_cursorline_03', {})
1089
1090 " clean up
1091 call StopVimInTerminal(buf)
Bram Moolenaar4a5abbd2018-10-02 18:26:10 +02001092endfunc
Bram Moolenaarf7acf2b2018-11-01 21:14:53 +01001093
Bram Moolenaar127969c2022-03-06 19:54:13 +00001094func Test_diff_with_cursorline_number()
1095 CheckScreendump
1096
1097 let lines =<< trim END
1098 hi CursorLine ctermbg=red ctermfg=white
1099 hi CursorLineNr ctermbg=white ctermfg=black cterm=underline
1100 set cursorline number
1101 call setline(1, ["baz", "foo", "foo", "bar"])
1102 2
1103 vnew
1104 call setline(1, ["foo", "foo", "bar"])
1105 windo diffthis
1106 1wincmd w
1107 END
Bram Moolenaar59173412022-09-20 22:01:33 +01001108 call writefile(lines, 'Xtest_diff_cursorline_number', 'D')
Bram Moolenaar127969c2022-03-06 19:54:13 +00001109 let buf = RunVimInTerminal('-S Xtest_diff_cursorline_number', {})
1110
1111 call VerifyScreenDump(buf, 'Test_diff_with_cursorline_number_01', {})
1112 call term_sendkeys(buf, ":set cursorlineopt=number\r")
1113 call VerifyScreenDump(buf, 'Test_diff_with_cursorline_number_02', {})
1114
1115 " clean up
1116 call StopVimInTerminal(buf)
Bram Moolenaar127969c2022-03-06 19:54:13 +00001117endfunc
1118
zeertzjq4f33bc22021-08-05 17:57:02 +02001119func Test_diff_with_cursorline_breakindent()
1120 CheckScreendump
1121
zeertzjq588f20d2023-12-05 15:47:09 +01001122 let lines =<< trim END
1123 hi CursorLine ctermbg=red ctermfg=white
1124 set noequalalways wrap diffopt=followwrap cursorline breakindent
1125 50vnew
1126 call setline(1, [' ', ' ', ' ', ' '])
1127 exe "norm! 20Afoo\<Esc>j20Afoo\<Esc>j20Afoo\<Esc>j20Abar\<Esc>"
1128 vnew
1129 call setline(1, [' ', ' ', ' ', ' '])
1130 exe "norm! 20Abee\<Esc>j20Afoo\<Esc>j20Afoo\<Esc>j20Abaz\<Esc>"
1131 windo diffthis
1132 2wincmd w
1133 END
1134 call writefile(lines, 'Xtest_diff_cursorline_breakindent', 'D')
zeertzjq4f33bc22021-08-05 17:57:02 +02001135 let buf = RunVimInTerminal('-S Xtest_diff_cursorline_breakindent', {})
1136
1137 call term_sendkeys(buf, "gg0")
1138 call VerifyScreenDump(buf, 'Test_diff_with_cul_bri_01', {})
1139 call term_sendkeys(buf, "j")
1140 call VerifyScreenDump(buf, 'Test_diff_with_cul_bri_02', {})
1141 call term_sendkeys(buf, "j")
1142 call VerifyScreenDump(buf, 'Test_diff_with_cul_bri_03', {})
1143 call term_sendkeys(buf, "j")
1144 call VerifyScreenDump(buf, 'Test_diff_with_cul_bri_04', {})
1145
1146 " clean up
1147 call StopVimInTerminal(buf)
zeertzjq4f33bc22021-08-05 17:57:02 +02001148endfunc
1149
zeertzjq588f20d2023-12-05 15:47:09 +01001150func Test_diff_breakindent_after_filler()
1151 CheckScreendump
1152
1153 let lines =<< trim END
zeertzjqf0a9d652024-02-12 22:53:20 +01001154 set laststatus=0 diffopt+=followwrap breakindent breakindentopt=min:0
zeertzjq588f20d2023-12-05 15:47:09 +01001155 call setline(1, ['a', ' ' .. repeat('c', 50)])
1156 vnew
1157 call setline(1, ['a', 'b', ' ' .. repeat('c', 50)])
1158 windo diffthis
1159 norm! G$
1160 END
1161 call writefile(lines, 'Xtest_diff_breakindent_after_filler', 'D')
1162 let buf = RunVimInTerminal('-S Xtest_diff_breakindent_after_filler', #{rows: 8, cols: 45})
1163 call VerifyScreenDump(buf, 'Test_diff_breakindent_after_filler', {})
1164
1165 " clean up
1166 call StopVimInTerminal(buf)
1167endfunc
1168
Bram Moolenaar248fdb32019-09-15 19:31:28 +02001169func Test_diff_with_syntax()
1170 CheckScreendump
1171
1172 let lines =<< trim END
Bram Moolenaar94722c52023-01-28 19:19:03 +00001173 void doNothing() {
Bram Moolenaar248fdb32019-09-15 19:31:28 +02001174 int x = 0;
1175 char *s = "hello";
1176 return 5;
1177 }
1178 END
Bram Moolenaar59173412022-09-20 22:01:33 +01001179 call writefile(lines, 'Xprogram1.c', 'D')
Bram Moolenaar248fdb32019-09-15 19:31:28 +02001180 let lines =<< trim END
Bram Moolenaar94722c52023-01-28 19:19:03 +00001181 void doSomething() {
Bram Moolenaar248fdb32019-09-15 19:31:28 +02001182 int x = 0;
1183 char *s = "there";
1184 return 5;
1185 }
1186 END
Bram Moolenaar59173412022-09-20 22:01:33 +01001187 call writefile(lines, 'Xprogram2.c', 'D')
Bram Moolenaar248fdb32019-09-15 19:31:28 +02001188
1189 let lines =<< trim END
Bram Moolenaar94722c52023-01-28 19:19:03 +00001190 edit Xprogram1.c
Bram Moolenaar248fdb32019-09-15 19:31:28 +02001191 diffsplit Xprogram2.c
1192 END
Bram Moolenaar59173412022-09-20 22:01:33 +01001193 call writefile(lines, 'Xtest_diff_syntax', 'D')
Bram Moolenaar248fdb32019-09-15 19:31:28 +02001194 let buf = RunVimInTerminal('-S Xtest_diff_syntax', {})
1195
1196 call VerifyScreenDump(buf, 'Test_diff_syntax_1', {})
1197
1198 " clean up
1199 call StopVimInTerminal(buf)
Bram Moolenaar248fdb32019-09-15 19:31:28 +02001200endfunc
1201
Bram Moolenaarf7acf2b2018-11-01 21:14:53 +01001202func Test_diff_of_diff()
Bram Moolenaar3c8ee622019-08-03 22:55:50 +02001203 CheckScreendump
1204 CheckFeature rightleft
Bram Moolenaarf7acf2b2018-11-01 21:14:53 +01001205
1206 call writefile([
1207 \ 'call setline(1, ["aa","bb","cc","@@ -3,2 +5,7 @@","dd","ee","ff"])',
1208 \ 'vnew',
1209 \ 'call setline(1, ["aa","bb","cc"])',
1210 \ 'windo diffthis',
Bram Moolenaar8ee4c012019-03-29 18:08:18 +01001211 \ '1wincmd w',
1212 \ 'setlocal number',
Bram Moolenaar59173412022-09-20 22:01:33 +01001213 \ ], 'Xtest_diff_diff', 'D')
Bram Moolenaarf7acf2b2018-11-01 21:14:53 +01001214 let buf = RunVimInTerminal('-S Xtest_diff_diff', {})
1215
1216 call VerifyScreenDump(buf, 'Test_diff_of_diff_01', {})
1217
Bram Moolenaare73f9112019-03-29 18:29:54 +01001218 call term_sendkeys(buf, ":set rightleft\<cr>")
1219 call VerifyScreenDump(buf, 'Test_diff_of_diff_02', {})
1220
Bram Moolenaarf7acf2b2018-11-01 21:14:53 +01001221 " clean up
1222 call StopVimInTerminal(buf)
Bram Moolenaarf7acf2b2018-11-01 21:14:53 +01001223endfunc
Bram Moolenaarc8234772019-11-10 21:00:27 +01001224
1225func CloseoffSetup()
1226 enew
1227 call setline(1, ['one', 'two', 'three'])
1228 diffthis
1229 new
1230 call setline(1, ['one', 'tow', 'three'])
1231 diffthis
1232 call assert_equal(1, &diff)
1233 only!
1234endfunc
1235
1236func Test_diff_closeoff()
1237 " "closeoff" included by default: last diff win gets 'diff' reset'
1238 call CloseoffSetup()
1239 call assert_equal(0, &diff)
1240 enew!
1241
1242 " "closeoff" excluded: last diff win keeps 'diff' set'
1243 set diffopt-=closeoff
1244 call CloseoffSetup()
1245 call assert_equal(1, &diff)
1246 diffoff!
1247 enew!
1248endfunc
Bram Moolenaarf4a1d1c2019-11-16 13:50:25 +01001249
Bram Moolenaar4223d432021-02-10 13:18:17 +01001250func Test_diff_followwrap()
1251 new
1252 set diffopt+=followwrap
1253 set wrap
1254 diffthis
1255 call assert_equal(1, &wrap)
1256 diffoff
1257 set nowrap
1258 diffthis
1259 call assert_equal(0, &wrap)
1260 diffoff
1261 set diffopt&
1262 bwipe!
1263endfunc
1264
Bram Moolenaarf4a1d1c2019-11-16 13:50:25 +01001265func Test_diff_maintains_change_mark()
Sean Dewarccc16442021-12-29 16:44:48 +00001266 func DiffMaintainsChangeMark()
1267 enew!
1268 call setline(1, ['a', 'b', 'c', 'd'])
1269 diffthis
1270 new
1271 call setline(1, ['a', 'b', 'c', 'e'])
1272 " Set '[ and '] marks
1273 2,3yank
1274 call assert_equal([2, 3], [line("'["), line("']")])
1275 " Verify they aren't affected by the implicit diff
1276 diffthis
1277 call assert_equal([2, 3], [line("'["), line("']")])
1278 " Verify they aren't affected by an explicit diff
1279 diffupdate
1280 call assert_equal([2, 3], [line("'["), line("']")])
1281 bwipe!
1282 bwipe!
1283 endfunc
1284
1285 set diffopt-=internal
1286 call DiffMaintainsChangeMark()
1287 set diffopt+=internal
1288 call DiffMaintainsChangeMark()
Bram Moolenaard9b74a22022-01-16 15:00:08 +00001289
Sean Dewarccc16442021-12-29 16:44:48 +00001290 set diffopt&
Bram Moolenaard9b74a22022-01-16 15:00:08 +00001291 delfunc DiffMaintainsChangeMark
Bram Moolenaarf4a1d1c2019-11-16 13:50:25 +01001292endfunc
Bram Moolenaar8dfcce32020-03-18 19:32:26 +01001293
1294" Test for 'patchexpr'
1295func Test_patchexpr()
1296 let g:patch_args = []
1297 func TPatch()
1298 call add(g:patch_args, readfile(v:fname_in))
1299 call add(g:patch_args, readfile(v:fname_diff))
1300 call writefile(['output file'], v:fname_out)
1301 endfunc
1302 set patchexpr=TPatch()
1303
Bram Moolenaar59173412022-09-20 22:01:33 +01001304 call writefile(['input file'], 'Xinput', 'D')
1305 call writefile(['diff file'], 'Xdiff', 'D')
Bram Moolenaar8dfcce32020-03-18 19:32:26 +01001306 %bwipe!
1307 edit Xinput
1308 diffpatch Xdiff
1309 call assert_equal('output file', getline(1))
1310 call assert_equal('Xinput.new', bufname())
1311 call assert_equal(2, winnr('$'))
1312 call assert_true(&diff)
1313
Yegappan Lakshmanan8bb65f22021-12-26 10:51:39 +00001314 " Using a script-local function
1315 func s:NewPatchExpr()
1316 endfunc
1317 set patchexpr=s:NewPatchExpr()
1318 call assert_equal(expand('<SID>') .. 'NewPatchExpr()', &patchexpr)
1319 set patchexpr=<SID>NewPatchExpr()
1320 call assert_equal(expand('<SID>') .. 'NewPatchExpr()', &patchexpr)
1321
Bram Moolenaar8dfcce32020-03-18 19:32:26 +01001322 set patchexpr&
1323 delfunc TPatch
Yegappan Lakshmanan8bb65f22021-12-26 10:51:39 +00001324 delfunc s:NewPatchExpr
Bram Moolenaar8dfcce32020-03-18 19:32:26 +01001325 %bwipe!
1326endfunc
1327
Bram Moolenaar511feec2020-06-18 19:15:27 +02001328func Test_diff_rnu()
1329 CheckScreendump
1330
1331 let content =<< trim END
1332 call setline(1, ['a', 'a', 'a', 'y', 'b', 'b', 'b', 'b', 'b'])
1333 vnew
1334 call setline(1, ['a', 'a', 'a', 'x', 'x', 'x', 'b', 'b', 'b', 'b', 'b'])
1335 windo diffthis
1336 setlocal number rnu foldcolumn=0
1337 END
Bram Moolenaar59173412022-09-20 22:01:33 +01001338 call writefile(content, 'Xtest_diff_rnu', 'D')
Bram Moolenaar511feec2020-06-18 19:15:27 +02001339 let buf = RunVimInTerminal('-S Xtest_diff_rnu', {})
1340
1341 call VerifyScreenDump(buf, 'Test_diff_rnu_01', {})
1342
1343 call term_sendkeys(buf, "j")
1344 call VerifyScreenDump(buf, 'Test_diff_rnu_02', {})
1345 call term_sendkeys(buf, "j")
1346 call VerifyScreenDump(buf, 'Test_diff_rnu_03', {})
1347
1348 " clean up
1349 call StopVimInTerminal(buf)
Bram Moolenaar511feec2020-06-18 19:15:27 +02001350endfunc
1351
Bram Moolenaarfc838d62020-06-25 22:23:48 +02001352func Test_diff_multilineconceal()
1353 new
1354 diffthis
1355
1356 new
1357 call matchadd('Conceal', 'a\nb', 9, -1, {'conceal': 'Y'})
1358 set cole=2 cocu=n
1359 call setline(1, ["a", "b"])
1360 diffthis
1361 redraw
1362endfunc
1363
Bram Moolenaar8455c5e2020-07-14 21:22:30 +02001364func Test_diff_and_scroll()
1365 " this was causing an ml_get error
1366 set ls=2
Bram Moolenaar94722c52023-01-28 19:19:03 +00001367 for i in range(winheight(0) * 2)
1368 call setline(i, i < winheight(0) - 10 ? i : i + 10)
Bram Moolenaar8455c5e2020-07-14 21:22:30 +02001369 endfor
1370 vnew
Bram Moolenaar94722c52023-01-28 19:19:03 +00001371 for i in range(winheight(0)*2 + 10)
1372 call setline(i, i < winheight(0) - 10 ? 0 : i)
Bram Moolenaar8455c5e2020-07-14 21:22:30 +02001373 endfor
1374 diffthis
1375 wincmd p
1376 diffthis
1377 execute 'normal ' . winheight(0) . "\<C-d>"
1378
1379 bwipe!
1380 bwipe!
1381 set ls&
1382endfunc
1383
Bram Moolenaarfabc3ca2020-11-05 19:07:21 +01001384func Test_diff_filler_cursorcolumn()
1385 CheckScreendump
1386
1387 let content =<< trim END
1388 call setline(1, ['aa', 'bb', 'cc'])
1389 vnew
1390 call setline(1, ['aa', 'cc'])
1391 windo diffthis
1392 wincmd p
1393 setlocal cursorcolumn foldcolumn=0
1394 norm! gg0
1395 redraw!
1396 END
Bram Moolenaar59173412022-09-20 22:01:33 +01001397 call writefile(content, 'Xtest_diff_cuc', 'D')
Bram Moolenaarfabc3ca2020-11-05 19:07:21 +01001398 let buf = RunVimInTerminal('-S Xtest_diff_cuc', {})
1399
1400 call VerifyScreenDump(buf, 'Test_diff_cuc_01', {})
1401
1402 call term_sendkeys(buf, "l")
1403 call term_sendkeys(buf, "\<C-l>")
1404 call VerifyScreenDump(buf, 'Test_diff_cuc_02', {})
1405 call term_sendkeys(buf, "0j")
1406 call term_sendkeys(buf, "\<C-l>")
1407 call VerifyScreenDump(buf, 'Test_diff_cuc_03', {})
1408 call term_sendkeys(buf, "l")
1409 call term_sendkeys(buf, "\<C-l>")
1410 call VerifyScreenDump(buf, 'Test_diff_cuc_04', {})
1411
1412 " clean up
1413 call StopVimInTerminal(buf)
Bram Moolenaarfabc3ca2020-11-05 19:07:21 +01001414endfunc
1415
Yegappan Lakshmanan30443242021-06-10 21:52:15 +02001416" Test for adding/removing lines inside diff chunks, between diff chunks
1417" and before diff chunks
1418func Test_diff_modify_chunks()
1419 enew!
1420 let w2_id = win_getid()
1421 call setline(1, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'])
1422 new
1423 let w1_id = win_getid()
1424 call setline(1, ['a', '2', '3', 'd', 'e', 'f', '7', '8', 'i'])
1425 windo diffthis
1426
1427 " remove a line between two diff chunks and create a new diff chunk
1428 call win_gotoid(w2_id)
1429 5d
1430 call win_gotoid(w1_id)
1431 call diff_hlID(5, 1)->synIDattr('name')->assert_equal('DiffAdd')
1432
1433 " add a line between two diff chunks
1434 call win_gotoid(w2_id)
1435 normal! 4Goe
1436 call win_gotoid(w1_id)
1437 call diff_hlID(4, 1)->synIDattr('name')->assert_equal('')
1438 call diff_hlID(5, 1)->synIDattr('name')->assert_equal('')
1439
1440 " remove all the lines in a diff chunk.
1441 call win_gotoid(w2_id)
1442 7,8d
1443 call win_gotoid(w1_id)
1444 let hl = range(1, 9)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')})
1445 call assert_equal(['', 'DiffText', 'DiffText', '', '', '', 'DiffAdd',
1446 \ 'DiffAdd', ''], hl)
1447
1448 " remove lines from one diff chunk to just before the next diff chunk
1449 call win_gotoid(w2_id)
1450 call setline(1, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'])
1451 2,6d
1452 call win_gotoid(w1_id)
1453 let hl = range(1, 9)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')})
1454 call assert_equal(['', 'DiffText', 'DiffText', 'DiffAdd', 'DiffAdd',
1455 \ 'DiffAdd', 'DiffAdd', 'DiffAdd', ''], hl)
1456
1457 " remove lines just before the top of a diff chunk
1458 call win_gotoid(w2_id)
1459 call setline(1, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'])
1460 5,6d
1461 call win_gotoid(w1_id)
1462 let hl = range(1, 9)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')})
1463 call assert_equal(['', 'DiffText', 'DiffText', '', 'DiffText', 'DiffText',
1464 \ 'DiffAdd', 'DiffAdd', ''], hl)
1465
1466 " remove line after the end of a diff chunk
1467 call win_gotoid(w2_id)
1468 call setline(1, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'])
1469 4d
1470 call win_gotoid(w1_id)
1471 let hl = range(1, 9)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')})
1472 call assert_equal(['', 'DiffText', 'DiffText', 'DiffAdd', '', '', 'DiffText',
1473 \ 'DiffText', ''], hl)
1474
1475 " remove lines starting from the end of one diff chunk and ending inside
1476 " another diff chunk
1477 call win_gotoid(w2_id)
1478 call setline(1, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'])
1479 4,7d
1480 call win_gotoid(w1_id)
1481 let hl = range(1, 9)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')})
1482 call assert_equal(['', 'DiffText', 'DiffText', 'DiffText', 'DiffAdd',
1483 \ 'DiffAdd', 'DiffAdd', 'DiffAdd', ''], hl)
1484
1485 " removing the only remaining diff chunk should make the files equal
1486 call win_gotoid(w2_id)
1487 call setline(1, ['a', '2', '3', 'x', 'd', 'e', 'f', 'x', '7', '8', 'i'])
1488 8d
1489 let hl = range(1, 10)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')})
1490 call assert_equal(['', '', '', 'DiffAdd', '', '', '', '', '', ''], hl)
1491 call win_gotoid(w2_id)
1492 4d
1493 call win_gotoid(w1_id)
1494 let hl = range(1, 9)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')})
1495 call assert_equal(['', '', '', '', '', '', '', '', ''], hl)
1496
1497 %bw!
1498endfunc
glacambread5c1782021-05-24 14:20:53 +02001499
Bram Moolenaar06f60952021-12-28 18:30:05 +00001500func Test_diff_binary()
1501 CheckScreendump
1502
1503 let content =<< trim END
1504 call setline(1, ['a', 'b', "c\n", 'd', 'e', 'f', 'g'])
1505 vnew
1506 call setline(1, ['A', 'b', 'c', 'd', 'E', 'f', 'g'])
1507 windo diffthis
1508 wincmd p
1509 norm! gg0
1510 redraw!
1511 END
Bram Moolenaar59173412022-09-20 22:01:33 +01001512 call writefile(content, 'Xtest_diff_bin', 'D')
Bram Moolenaar06f60952021-12-28 18:30:05 +00001513 let buf = RunVimInTerminal('-S Xtest_diff_bin', {})
1514
1515 " Test using internal diff
1516 call VerifyScreenDump(buf, 'Test_diff_bin_01', {})
1517
1518 " Test using internal diff and case folding
1519 call term_sendkeys(buf, ":set diffopt+=icase\<cr>")
1520 call term_sendkeys(buf, "\<C-l>")
1521 call VerifyScreenDump(buf, 'Test_diff_bin_02', {})
1522 " Test using external diff
1523 call term_sendkeys(buf, ":set diffopt=filler\<cr>")
1524 call term_sendkeys(buf, "\<C-l>")
1525 call VerifyScreenDump(buf, 'Test_diff_bin_03', {})
1526 " Test using external diff and case folding
1527 call term_sendkeys(buf, ":set diffopt=filler,icase\<cr>")
1528 call term_sendkeys(buf, "\<C-l>")
1529 call VerifyScreenDump(buf, 'Test_diff_bin_04', {})
1530
1531 " clean up
1532 call StopVimInTerminal(buf)
Bram Moolenaar06f60952021-12-28 18:30:05 +00001533 set diffopt&vim
1534endfunc
1535
Yegappan Lakshmananb0ad2d92022-01-27 13:16:59 +00001536" Test for using the 'zi' command to invert 'foldenable' in diff windows (test
1537" for the issue fixed by patch 6.2.317)
1538func Test_diff_foldinvert()
1539 %bw!
Bram Moolenaar61abe7d2022-08-30 21:46:08 +01001540 edit Xdoffile1
1541 new Xdoffile2
1542 new Xdoffile3
Yegappan Lakshmananb0ad2d92022-01-27 13:16:59 +00001543 windo diffthis
1544 " open a non-diff window
1545 botright new
1546 1wincmd w
1547 call assert_true(getwinvar(1, '&foldenable'))
1548 call assert_true(getwinvar(2, '&foldenable'))
1549 call assert_true(getwinvar(3, '&foldenable'))
1550 normal zi
1551 call assert_false(getwinvar(1, '&foldenable'))
1552 call assert_false(getwinvar(2, '&foldenable'))
1553 call assert_false(getwinvar(3, '&foldenable'))
1554 normal zi
1555 call assert_true(getwinvar(1, '&foldenable'))
1556 call assert_true(getwinvar(2, '&foldenable'))
1557 call assert_true(getwinvar(3, '&foldenable'))
1558
1559 " If the current window has 'noscrollbind', then 'zi' should not change
1560 " 'foldenable' in other windows.
1561 1wincmd w
1562 set noscrollbind
1563 normal zi
1564 call assert_false(getwinvar(1, '&foldenable'))
1565 call assert_true(getwinvar(2, '&foldenable'))
1566 call assert_true(getwinvar(3, '&foldenable'))
1567
1568 " 'zi' should not change the 'foldenable' for windows with 'noscrollbind'
1569 1wincmd w
1570 set scrollbind
1571 normal zi
1572 call setwinvar(2, '&scrollbind', v:false)
1573 normal zi
1574 call assert_false(getwinvar(1, '&foldenable'))
1575 call assert_true(getwinvar(2, '&foldenable'))
1576 call assert_false(getwinvar(3, '&foldenable'))
1577
1578 %bw!
1579 set scrollbind&
1580endfunc
1581
Bram Moolenaara315ce12022-06-24 12:38:57 +01001582" This was scrolling for 'cursorbind' but 'scrollbind' is more important
1583func Test_diff_scroll()
1584 CheckScreendump
1585
1586 let left =<< trim END
1587 line 1
1588 line 2
1589 line 3
1590 line 4
1591
1592 // Common block
1593 // one
1594 // containing
1595 // four lines
1596
1597 // Common block
1598 // two
1599 // containing
1600 // four lines
1601 END
Bram Moolenaar59173412022-09-20 22:01:33 +01001602 call writefile(left, 'Xleft', 'D')
Bram Moolenaara315ce12022-06-24 12:38:57 +01001603 let right =<< trim END
1604 line 1
1605 line 2
1606 line 3
1607 line 4
1608
1609 Lorem
1610 ipsum
1611 dolor
1612 sit
1613 amet,
1614 consectetur
1615 adipiscing
1616 elit.
1617 Etiam
1618 luctus
1619 lectus
1620 sodales,
1621 dictum
1622
1623 // Common block
1624 // one
1625 // containing
1626 // four lines
1627
1628 Vestibulum
1629 tincidunt
1630 aliquet
1631 nulla.
1632
1633 // Common block
1634 // two
1635 // containing
1636 // four lines
1637 END
Bram Moolenaar59173412022-09-20 22:01:33 +01001638 call writefile(right, 'Xright', 'D')
Bram Moolenaara315ce12022-06-24 12:38:57 +01001639 let buf = RunVimInTerminal('-d Xleft Xright', {'rows': 12})
1640 call term_sendkeys(buf, "\<C-W>\<C-W>jjjj")
1641 call VerifyScreenDump(buf, 'Test_diff_scroll_1', {})
1642 call term_sendkeys(buf, "j")
1643 call VerifyScreenDump(buf, 'Test_diff_scroll_2', {})
1644
1645 call StopVimInTerminal(buf)
Bram Moolenaara315ce12022-06-24 12:38:57 +01001646endfunc
1647
Bram Moolenaar38d867f2023-04-01 19:54:40 +01001648" This was scrolling too many lines.
1649func Test_diff_scroll_wrap_on()
1650 20new
1651 40vsplit
1652 call setline(1, map(range(1, 9), 'repeat(v:val, 200)'))
1653 setlocal number diff so=0
1654 redraw
1655 normal! jj
1656 call assert_equal(1, winsaveview().topline)
1657 normal! j
1658 call assert_equal(2, winsaveview().topline)
zeertzjq05834912023-10-04 20:12:37 +02001659
1660 bwipe!
1661 bwipe!
1662endfunc
1663
1664func Test_diff_scroll_many_filler()
1665 20new
1666 vnew
Luuk van Baalb9f5b952024-03-26 18:46:45 +01001667 call setline(1, range(1, 40))
zeertzjq05834912023-10-04 20:12:37 +02001668 diffthis
1669 setlocal scrolloff=0
1670 wincmd p
Luuk van Baalb9f5b952024-03-26 18:46:45 +01001671 call setline(1, range(1, 20)->reverse() + ['###']->repeat(41) + range(21, 40)->reverse())
zeertzjq05834912023-10-04 20:12:37 +02001672 diffthis
1673 setlocal scrolloff=0
1674 wincmd p
1675 redraw
1676
1677 " Note: need a redraw after each scroll, otherwise the test always passes.
Luuk van Baalb9f5b952024-03-26 18:46:45 +01001678 for _ in range(2)
1679 normal! G
1680 redraw
1681 call assert_equal(40, winsaveview().topline)
1682 call assert_equal(19, winsaveview().topfill)
1683 exe "normal! \<C-B>"
1684 redraw
1685 call assert_equal(22, winsaveview().topline)
1686 call assert_equal(0, winsaveview().topfill)
1687 exe "normal! \<C-B>"
1688 redraw
1689 call assert_equal(4, winsaveview().topline)
1690 call assert_equal(0, winsaveview().topfill)
1691 exe "normal! \<C-B>"
1692 redraw
1693 call assert_equal(1, winsaveview().topline)
1694 call assert_equal(0, winsaveview().topfill)
1695 set smoothscroll
1696 endfor
zeertzjq05834912023-10-04 20:12:37 +02001697
Luuk van Baalb9f5b952024-03-26 18:46:45 +01001698 set smoothscroll&
Luuk van Baalcb204e62024-04-02 20:49:45 +02001699 %bwipe!
Bram Moolenaar38d867f2023-04-01 19:54:40 +01001700endfunc
1701
Bram Moolenaarcd38bb42022-06-26 14:04:07 +01001702" This was trying to update diffs for a buffer being closed
1703func Test_diff_only()
1704 silent! lfile
1705 set diff
1706 lopen
1707 norm o
1708 silent! norm o
1709
1710 set nodiff
1711 %bwipe!
1712endfunc
1713
Bram Moolenaarc101abf2022-06-26 16:53:34 +01001714" This was causing invalid diff block values
1715" FIXME: somehow this causes a valgrind error when run directly but not when
1716" run as a test.
1717func Test_diff_manipulations()
1718 set diff
1719 split 0
1720 sil! norm R doobdeuR doobdeuR doobdeu
1721
1722 set nodiff
1723 %bwipe!
1724endfunc
1725
Bram Moolenaar4e677b92022-07-28 18:44:27 +01001726" This was causing the line number in the diff block to go below one.
1727" FIXME: somehow this causes a valgrind error when run directly but not when
1728" run as a test.
1729func Test_diff_put_and_undo()
1730 set diff
1731 next 0
1732 split 00
1733 sil! norm o0gguudpo0ggJuudp
1734
1735 bwipe!
1736 bwipe!
1737 set nodiff
1738endfunc
1739
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001740" Test for the diff() function
1741def Test_diff_func()
1742 # string is added/removed/modified at the beginning
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001743 assert_equal("@@ -0,0 +1 @@\n+abc\n",
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001744 diff(['def'], ['abc', 'def'], {output: 'unified'}))
1745 assert_equal([{from_idx: 0, from_count: 0, to_idx: 0, to_count: 1}],
1746 diff(['def'], ['abc', 'def'], {output: 'indices'}))
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001747 assert_equal("@@ -1 +0,0 @@\n-abc\n",
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001748 diff(['abc', 'def'], ['def'], {output: 'unified'}))
1749 assert_equal([{from_idx: 0, from_count: 1, to_idx: 0, to_count: 0}],
1750 diff(['abc', 'def'], ['def'], {output: 'indices'}))
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001751 assert_equal("@@ -1 +1 @@\n-abc\n+abx\n",
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001752 diff(['abc', 'def'], ['abx', 'def'], {output: 'unified'}))
1753 assert_equal([{from_idx: 0, from_count: 1, to_idx: 0, to_count: 1}],
1754 diff(['abc', 'def'], ['abx', 'def'], {output: 'indices'}))
1755
1756 # string is added/removed/modified at the end
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001757 assert_equal("@@ -1,0 +2 @@\n+def\n",
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001758 diff(['abc'], ['abc', 'def'], {output: 'unified'}))
1759 assert_equal([{from_idx: 1, from_count: 0, to_idx: 1, to_count: 1}],
1760 diff(['abc'], ['abc', 'def'], {output: 'indices'}))
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001761 assert_equal("@@ -2 +1,0 @@\n-def\n",
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001762 diff(['abc', 'def'], ['abc'], {output: 'unified'}))
1763 assert_equal([{from_idx: 1, from_count: 1, to_idx: 1, to_count: 0}],
1764 diff(['abc', 'def'], ['abc'], {output: 'indices'}))
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001765 assert_equal("@@ -2 +2 @@\n-def\n+xef\n",
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001766 diff(['abc', 'def'], ['abc', 'xef'], {output: 'unified'}))
1767 assert_equal([{from_idx: 1, from_count: 1, to_idx: 1, to_count: 1}],
1768 diff(['abc', 'def'], ['abc', 'xef'], {output: 'indices'}))
1769
1770 # string is added/removed/modified in the middle
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001771 assert_equal("@@ -2,0 +3 @@\n+xxx\n",
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001772 diff(['111', '222', '333'], ['111', '222', 'xxx', '333'], {output: 'unified'}))
1773 assert_equal([{from_idx: 2, from_count: 0, to_idx: 2, to_count: 1}],
1774 diff(['111', '222', '333'], ['111', '222', 'xxx', '333'], {output: 'indices'}))
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001775 assert_equal("@@ -3 +2,0 @@\n-333\n",
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001776 diff(['111', '222', '333', '444'], ['111', '222', '444'], {output: 'unified'}))
1777 assert_equal([{from_idx: 2, from_count: 1, to_idx: 2, to_count: 0}],
1778 diff(['111', '222', '333', '444'], ['111', '222', '444'], {output: 'indices'}))
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001779 assert_equal("@@ -3 +3 @@\n-333\n+xxx\n",
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001780 diff(['111', '222', '333', '444'], ['111', '222', 'xxx', '444'], {output: 'unified'}))
1781 assert_equal([{from_idx: 2, from_count: 1, to_idx: 2, to_count: 1}],
1782 diff(['111', '222', '333', '444'], ['111', '222', 'xxx', '444'], {output: 'indices'}))
1783
1784 # new strings are added to an empty List
1785 assert_equal("@@ -0,0 +1,2 @@\n+abc\n+def\n",
1786 diff([], ['abc', 'def'], {output: 'unified'}))
1787 assert_equal([{from_idx: 0, from_count: 0, to_idx: 0, to_count: 2}],
1788 diff([], ['abc', 'def'], {output: 'indices'}))
1789
1790 # all the strings are removed from a List
1791 assert_equal("@@ -1,2 +0,0 @@\n-abc\n-def\n",
1792 diff(['abc', 'def'], [], {output: 'unified'}))
1793 assert_equal([{from_idx: 0, from_count: 2, to_idx: 0, to_count: 0}],
1794 diff(['abc', 'def'], [], {output: 'indices'}))
1795
1796 # First character is added/removed/different
1797 assert_equal("@@ -1 +1 @@\n-abc\n+bc\n",
1798 diff(['abc'], ['bc'], {output: 'unified'}))
1799 assert_equal([{from_idx: 0, from_count: 1, to_idx: 0, to_count: 1}],
1800 diff(['abc'], ['bc'], {output: 'indices'}))
1801 assert_equal("@@ -1 +1 @@\n-bc\n+abc\n",
1802 diff(['bc'], ['abc'], {output: 'unified'}))
1803 assert_equal([{from_idx: 0, from_count: 1, to_idx: 0, to_count: 1}],
1804 diff(['bc'], ['abc'], {output: 'indices'}))
1805 assert_equal("@@ -1 +1 @@\n-abc\n+xbc\n",
1806 diff(['abc'], ['xbc'], {output: 'unified'}))
1807 assert_equal([{from_idx: 0, from_count: 1, to_idx: 0, to_count: 1}],
1808 diff(['abc'], ['xbc'], {output: 'indices'}))
1809
1810 # Last character is added/removed/different
1811 assert_equal("@@ -1 +1 @@\n-abc\n+abcd\n",
1812 diff(['abc'], ['abcd'], {output: 'unified'}))
1813 assert_equal([{from_idx: 0, from_count: 1, to_idx: 0, to_count: 1}],
1814 diff(['abc'], ['abcd'], {output: 'indices'}))
1815 assert_equal("@@ -1 +1 @@\n-abcd\n+abc\n",
1816 diff(['abcd'], ['abc'], {output: 'unified'}))
1817 assert_equal([{from_idx: 0, from_count: 1, to_idx: 0, to_count: 1}],
1818 diff(['abcd'], ['abc'], {output: 'indices'}))
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001819 var diff_unified: string = diff(['abc'], ['abx'], {output: 'unified'})
1820 assert_equal("@@ -1 +1 @@\n-abc\n+abx\n", diff_unified)
1821 var diff_indices: list<dict<number>> =
1822 diff(['abc'], ['abx'], {output: 'indices'})
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001823 assert_equal([{from_idx: 0, from_count: 1, to_idx: 0, to_count: 1}],
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001824 diff_indices)
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001825
1826 # partial string modification at the start and at the end.
1827 var fromlist =<< trim END
1828 one two
1829 three four
1830 five six
1831 END
1832 var tolist =<< trim END
1833 one
1834 six
1835 END
1836 assert_equal("@@ -1,3 +1,2 @@\n-one two\n-three four\n-five six\n+one\n+six\n", diff(fromlist, tolist, {output: 'unified'}))
1837 assert_equal([{from_idx: 0, from_count: 3, to_idx: 0, to_count: 2}],
1838 diff(fromlist, tolist, {output: 'indices'}))
1839
1840 # non-contiguous modifications
1841 fromlist =<< trim END
1842 one two
1843 three four
1844 five abc six
1845 END
1846 tolist =<< trim END
1847 one abc two
1848 three four
1849 five six
1850 END
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001851 assert_equal("@@ -1 +1 @@\n-one two\n+one abc two\n@@ -3 +3 @@\n-five abc six\n+five six\n",
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001852 diff(fromlist, tolist, {output: 'unified'}))
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001853 assert_equal([{'from_count': 1, 'to_idx': 0, 'to_count': 1, 'from_idx': 0},
1854 {'from_count': 1, 'to_idx': 2, 'to_count': 1, 'from_idx': 2}],
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001855 diff(fromlist, tolist, {output: 'indices'}))
1856
1857 # add/remove blank lines
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001858 assert_equal("@@ -2,2 +1,0 @@\n-\n-\n",
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001859 diff(['one', '', '', 'two'], ['one', 'two'], {output: 'unified'}))
1860 assert_equal([{from_idx: 1, from_count: 2, to_idx: 1, to_count: 0}],
1861 diff(['one', '', '', 'two'], ['one', 'two'], {output: 'indices'}))
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001862 assert_equal("@@ -1,0 +2,2 @@\n+\n+\n",
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001863 diff(['one', 'two'], ['one', '', '', 'two'], {output: 'unified'}))
1864 assert_equal([{'from_idx': 1, 'from_count': 0, 'to_idx': 1, 'to_count': 2}],
1865 diff(['one', 'two'], ['one', '', '', 'two'], {output: 'indices'}))
1866
1867 # diff ignoring case
1868 assert_equal('', diff(['abc', 'def'], ['ABC', 'DEF'], {icase: true, output: 'unified'}))
1869 assert_equal([], diff(['abc', 'def'], ['ABC', 'DEF'], {icase: true, output: 'indices'}))
1870
1871 # diff ignoring all whitespace changes except leading whitespace changes
1872 assert_equal('', diff(['abc def'], ['abc def '], {iwhite: true}))
1873 assert_equal("@@ -1 +1 @@\n- abc\n+ xxx\n", diff([' abc'], [' xxx'], {iwhite: v:true}))
1874 assert_equal("@@ -1 +1 @@\n- abc\n+ xxx\n", diff([' abc'], [' xxx'], {iwhite: v:false}))
1875 assert_equal("@@ -1 +1 @@\n-abc \n+xxx \n", diff(['abc '], ['xxx '], {iwhite: v:true}))
1876 assert_equal("@@ -1 +1 @@\n-abc \n+xxx \n", diff(['abc '], ['xxx '], {iwhite: v:false}))
1877
1878 # diff ignoring all whitespace changes
1879 assert_equal('', diff(['abc def'], [' abc def '], {iwhiteall: true}))
1880 assert_equal("@@ -1 +1 @@\n- abc \n+ xxx \n", diff([' abc '], [' xxx '], {iwhiteall: v:true}))
1881 assert_equal("@@ -1 +1 @@\n- abc \n+ xxx \n", diff([' abc '], [' xxx '], {iwhiteall: v:false}))
1882
1883 # diff ignoring trailing whitespace changes
1884 assert_equal('', diff(['abc'], ['abc '], {iwhiteeol: true}))
1885
1886 # diff ignoring blank lines
1887 assert_equal('', diff(['one', '', '', 'two'], ['one', 'two'], {iblank: true}))
1888 assert_equal('', diff(['one', 'two'], ['one', '', '', 'two'], {iblank: true}))
1889
1890 # same string
1891 assert_equal('', diff(['abc', 'def', 'ghi'], ['abc', 'def', 'ghi']))
1892 assert_equal('', diff([''], ['']))
1893 assert_equal('', diff([], []))
1894
1895 # different xdiff algorithms
1896 for algo in ['myers', 'minimal', 'patience', 'histogram']
1897 assert_equal("@@ -1 +1 @@\n- abc \n+ xxx \n",
1898 diff([' abc '], [' xxx '], {algorithm: algo, output: 'unified'}))
1899 assert_equal([{from_idx: 0, from_count: 1, to_idx: 0, to_count: 1}],
1900 diff([' abc '], [' xxx '], {algorithm: algo, output: 'indices'}))
1901 endfor
1902 assert_equal("@@ -1 +1 @@\n- abc \n+ xxx \n",
1903 diff([' abc '], [' xxx '], {indent-heuristic: true, output: 'unified'}))
1904 assert_equal([{from_idx: 0, from_count: 1, to_idx: 0, to_count: 1}],
1905 diff([' abc '], [' xxx '], {indent-heuristic: true, output: 'indices'}))
1906
1907 # identical strings
1908 assert_equal('', diff(['111', '222'], ['111', '222'], {output: 'unified'}))
1909 assert_equal([], diff(['111', '222'], ['111', '222'], {output: 'indices'}))
1910 assert_equal('', diff([], [], {output: 'unified'}))
1911 assert_equal([], diff([], [], {output: 'indices'}))
1912
Yegappan Lakshmananbe156a32024-02-11 17:08:29 +01001913 # If 'diffexpr' is set, it should not be used for diff()
1914 def MyDiffExpr()
1915 enddef
1916 var save_diffexpr = &diffexpr
1917 :set diffexpr=MyDiffExpr()
1918 assert_equal("@@ -1 +1 @@\n-abc\n+\n",
1919 diff(['abc'], [''], {output: 'unified'}))
1920 assert_equal([{'from_idx': 0, 'from_count': 1, 'to_idx': 0, 'to_count': 1}],
1921 diff(['abc'], [''], {output: 'indices'}))
1922 assert_equal('MyDiffExpr()', &diffexpr)
1923 &diffexpr = save_diffexpr
1924
1925 # try different values for unified diff 'context'
1926 assert_equal("@@ -0,0 +1 @@\n+x\n",
1927 diff(['a', 'b', 'c'], ['x', 'a', 'b', 'c']))
1928 assert_equal("@@ -0,0 +1 @@\n+x\n",
1929 diff(['a', 'b', 'c'], ['x', 'a', 'b', 'c'], {context: 0}))
1930 assert_equal("@@ -1 +1,2 @@\n+x\n a\n",
1931 diff(['a', 'b', 'c'], ['x', 'a', 'b', 'c'], {context: 1}))
1932 assert_equal("@@ -1,2 +1,3 @@\n+x\n a\n b\n",
1933 diff(['a', 'b', 'c'], ['x', 'a', 'b', 'c'], {context: 2}))
1934 assert_equal("@@ -1,3 +1,4 @@\n+x\n a\n b\n c\n",
1935 diff(['a', 'b', 'c'], ['x', 'a', 'b', 'c'], {context: 3}))
1936 assert_equal("@@ -1,3 +1,4 @@\n+x\n a\n b\n c\n",
1937 diff(['a', 'b', 'c'], ['x', 'a', 'b', 'c'], {context: 4}))
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001938 assert_equal("@@ -0,0 +1 @@\n+x\n",
Yegappan Lakshmananbe156a32024-02-11 17:08:29 +01001939 diff(['a', 'b', 'c'], ['x', 'a', 'b', 'c'], {context: -1}))
1940
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001941 # Error cases
1942 assert_fails('call diff({}, ["a"])', 'E1211:')
1943 assert_fails('call diff(["a"], {})', 'E1211:')
1944 assert_fails('call diff(["a"], ["a"], [])', 'E1206:')
1945 assert_fails('call diff(["a"], ["a"], {output: "xyz"})', 'E106: Unsupported diff output format: xyz')
Yegappan Lakshmananbe156a32024-02-11 17:08:29 +01001946 assert_fails('call diff(["a"], ["a"], {context: []})', 'E745: Using a List as a Number')
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001947enddef
Bram Moolenaara315ce12022-06-24 12:38:57 +01001948
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001949" Test for using the diff() function with 'diffexpr'
1950func Test_diffexpr_with_diff_func()
1951 CheckScreendump
1952
1953 let lines =<< trim END
1954 def DiffFuncExpr()
1955 var in: list<string> = readfile(v:fname_in)
1956 var new: list<string> = readfile(v:fname_new)
1957 var out: string = diff(in, new)
1958 writefile(split(out, "\n"), v:fname_out)
1959 enddef
1960 set diffexpr=DiffFuncExpr()
1961
1962 edit Xdifffunc1.txt
1963 diffthis
1964 vert split Xdifffunc2.txt
1965 diffthis
1966 END
1967 call writefile(lines, 'XsetupDiffFunc.vim', 'D')
1968
1969 call writefile(['zero', 'one', 'two', 'three'], 'Xdifffunc1.txt', 'D')
1970 call writefile(['one', 'twox', 'three', 'four'], 'Xdifffunc2.txt', 'D')
1971
1972 let buf = RunVimInTerminal('-S XsetupDiffFunc.vim', {'rows': 12})
1973 call VerifyScreenDump(buf, 'Test_difffunc_diffexpr_1', {})
1974 call StopVimInTerminal(buf)
1975endfunc
1976
zeertzjq9e7f1fc2024-03-16 09:40:22 +01001977func Test_diff_toggle_wrap_skipcol_leftcol()
1978 61vnew
1979 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.')
1980 30vnew
1981 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.')
1982 let win1 = win_getid()
1983 setlocal smoothscroll
1984 exe "normal! $\<C-E>"
1985 wincmd l
1986 let win2 = win_getid()
1987 setlocal smoothscroll
1988 exe "normal! $\<C-E>"
1989 call assert_equal([
1990 \ '<<<sadipscing elitr, sed diam |<<<tetur sadipscing elitr, sed|',
1991 \ 'nonumy eirmod tempor invidunt | diam nonumy eirmod tempor inv|',
1992 \ 'ut labore et dolore magna aliq|idunt ut labore et dolore magn|',
1993 \ 'uyam erat, sed diam voluptua. |a aliquyam erat, sed diam volu|',
1994 \ '~ |ptua. |',
1995 \ ], ScreenLines([1, 5], 62))
1996 call assert_equal({'col': 29, 'row': 4, 'endcol': 29, 'curscol': 29},
1997 \ screenpos(win1, line('.', win1), col('.', win1)))
1998 call assert_equal({'col': 36, 'row': 5, 'endcol': 36, 'curscol': 36},
1999 \ screenpos(win2, line('.', win2), col('.', win2)))
2000
2001 wincmd h
2002 diffthis
2003 wincmd l
2004 diffthis
2005 normal! 0
2006 call assert_equal([
2007 \ ' ipsum dolor sit amet, conset| Lorem ipsum dolor sit amet, |',
2008 \ '~ |~ |',
2009 \ ], ScreenLines([1, 2], 62))
2010 call assert_equal({'col': 3, 'row': 1, 'endcol': 3, 'curscol': 3},
2011 \ screenpos(win1, line('.', win1), col('.', win1)))
2012 call assert_equal({'col': 34, 'row': 1, 'endcol': 34, 'curscol': 34},
2013 \ screenpos(win2, line('.', win2), col('.', win2)))
2014
2015 normal! $
2016 call assert_equal([
2017 \ ' voluptua. | diam voluptua. |',
2018 \ '~ |~ |',
2019 \ ], ScreenLines([1, 2], 62))
2020 call assert_equal({'col': 11, 'row': 1, 'endcol': 11, 'curscol': 11},
2021 \ screenpos(win1, line('.', win1), col('.', win1)))
2022 call assert_equal({'col': 48, 'row': 1, 'endcol': 48, 'curscol': 48},
2023 \ screenpos(win2, line('.', win2), col('.', win2)))
2024
2025 diffoff!
2026 call assert_equal([
2027 \ 'ipsum dolor sit amet, consetet|Lorem ipsum dolor sit amet, co|',
2028 \ 'ur sadipscing elitr, sed diam |nsetetur sadipscing elitr, sed|',
2029 \ 'nonumy eirmod tempor invidunt | diam nonumy eirmod tempor inv|',
2030 \ 'ut labore et dolore magna aliq|idunt ut labore et dolore magn|',
2031 \ 'uyam erat, sed diam voluptua. |a aliquyam erat, sed diam volu|',
2032 \ '~ |ptua. |',
2033 \ ], ScreenLines([1, 6], 62))
2034 call assert_equal({'col': 29, 'row': 5, 'endcol': 29, 'curscol': 29},
2035 \ screenpos(win1, line('.', win1), col('.', win1)))
2036 call assert_equal({'col': 36, 'row': 6, 'endcol': 36, 'curscol': 36},
2037 \ screenpos(win2, line('.', win2), col('.', win2)))
2038
2039 bwipe!
2040 bwipe!
2041endfunc
2042
Luuk van Baal9148ba82024-04-08 22:27:41 +02002043" Ctrl-D reveals filler lines below the last line in the buffer.
2044func Test_diff_eob_halfpage()
Luuk van Baal08b0f632024-04-09 22:43:49 +02002045 new
Luuk van Baal9148ba82024-04-08 22:27:41 +02002046 call setline(1, ['']->repeat(10) + ['a'])
2047 diffthis
Luuk van Baal08b0f632024-04-09 22:43:49 +02002048 new
Luuk van Baal9148ba82024-04-08 22:27:41 +02002049 call setline(1, ['']->repeat(3) + ['a', 'b'])
2050 diffthis
Luuk van Baal08b0f632024-04-09 22:43:49 +02002051 resize 5
Luuk van Baal9148ba82024-04-08 22:27:41 +02002052 wincmd j
Luuk van Baal08b0f632024-04-09 22:43:49 +02002053 resize 5
2054 norm G
2055 call assert_equal(7, line('w0'))
2056 exe "norm! \<C-D>"
2057 call assert_equal(8, line('w0'))
Luuk van Baal9148ba82024-04-08 22:27:41 +02002058
2059 %bwipe!
2060endfunc
2061
Yukihiro Nakadaira06fe70c2024-09-26 16:19:42 +02002062func Test_diff_overlapped_diff_blocks_will_be_merged()
2063 CheckScreendump
2064
2065 let lines =<< trim END
2066 func DiffExprStub()
2067 let txt_in = readfile(v:fname_in)
2068 let txt_new = readfile(v:fname_new)
2069 if txt_in == ["line1"] && txt_new == ["line2"]
2070 call writefile(["1c1"], v:fname_out)
2071 elseif txt_in == readfile("Xdiin1") && txt_new == readfile("Xdinew1")
2072 call writefile(readfile("Xdiout1"), v:fname_out)
2073 elseif txt_in == readfile("Xdiin2") && txt_new == readfile("Xdinew2")
2074 call writefile(readfile("Xdiout2"), v:fname_out)
2075 endif
2076 endfunc
2077 END
2078 call writefile(lines, 'XdiffSetup', 'D')
2079
2080 call WriteDiffFiles(0, [], [])
2081 let buf = RunVimInTerminal('-d -S XdiffSetup Xdifile1 Xdifile2', {})
2082 call term_sendkeys(buf, ":set autoread\<CR>\<c-w>w:set autoread\<CR>\<c-w>w")
2083
2084 call WriteDiffFiles(buf, ["a", "b"], ["x", "x"])
2085 call writefile(["a", "b"], "Xdiin1")
2086 call writefile(["x", "x"], "Xdinew1")
2087 call writefile(["1c1", "2c2"], "Xdiout1")
2088 call term_sendkeys(buf, ":set diffexpr=DiffExprStub()\<CR>:")
2089 call VerifyBoth(buf, "Test_diff_overlapped_2.01", "")
2090 call term_sendkeys(buf, ":set diffexpr&\<CR>:")
2091
2092 call WriteDiffFiles(buf, ["a", "b", "c"], ["x", "c"])
2093 call writefile(["a", "b", "c"], "Xdiin1")
2094 call writefile(["x", "c"], "Xdinew1")
2095 call writefile(["1c1", "2d1"], "Xdiout1")
2096 call term_sendkeys(buf, ":set diffexpr=DiffExprStub()\<CR>:")
2097 call VerifyBoth(buf, "Test_diff_overlapped_2.02", "")
2098 call term_sendkeys(buf, ":set diffexpr&\<CR>:")
2099
2100 call WriteDiffFiles(buf, ["a", "c"], ["x", "x", "c"])
2101 call writefile(["a", "c"], "Xdiin1")
2102 call writefile(["x", "x", "c"], "Xdinew1")
2103 call writefile(["1c1", "1a2"], "Xdiout1")
2104 call term_sendkeys(buf, ":set diffexpr=DiffExprStub()\<CR>:")
2105 call VerifyBoth(buf, "Test_diff_overlapped_2.03", "")
2106 call term_sendkeys(buf, ":set diffexpr&\<CR>:")
2107
2108 call StopVimInTerminal(buf)
2109 wincmd c
2110
2111 call WriteDiffFiles3(0, [], [], [])
2112 let buf = RunVimInTerminal('-d -S XdiffSetup Xdifile1 Xdifile2 Xdifile3', {})
2113 call term_sendkeys(buf, ":set autoread\<CR>\<c-w>w:set autoread\<CR>\<c-w>w:set autoread\<CR>\<c-w>w")
2114
2115 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["y", "b", "c"])
2116 call VerifyBoth(buf, "Test_diff_overlapped_3.01", "")
2117
2118 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["a", "y", "c"])
2119 call VerifyBoth(buf, "Test_diff_overlapped_3.02", "")
2120
2121 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["a", "b", "y"])
2122 call VerifyBoth(buf, "Test_diff_overlapped_3.03", "")
2123
2124 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["y", "y", "c"])
2125 call VerifyBoth(buf, "Test_diff_overlapped_3.04", "")
2126
2127 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["a", "y", "y"])
2128 call VerifyBoth(buf, "Test_diff_overlapped_3.05", "")
2129
2130 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["y", "y", "y"])
2131 call VerifyBoth(buf, "Test_diff_overlapped_3.06", "")
2132
2133 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "x"], ["y", "y", "c"])
2134 call VerifyBoth(buf, "Test_diff_overlapped_3.07", "")
2135
2136 call WriteDiffFiles3(buf, ["a", "b", "c"], ["x", "x", "c"], ["a", "y", "y"])
2137 call VerifyBoth(buf, "Test_diff_overlapped_3.08", "")
2138
2139 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["y", "y", "y", "d", "e"])
2140 call VerifyBoth(buf, "Test_diff_overlapped_3.09", "")
2141
2142 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["y", "y", "y", "y", "e"])
2143 call VerifyBoth(buf, "Test_diff_overlapped_3.10", "")
2144
2145 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["y", "y", "y", "y", "y"])
2146 call VerifyBoth(buf, "Test_diff_overlapped_3.11", "")
2147
2148 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "y", "y", "d", "e"])
2149 call VerifyBoth(buf, "Test_diff_overlapped_3.12", "")
2150
2151 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "y", "y", "y", "e"])
2152 call VerifyBoth(buf, "Test_diff_overlapped_3.13", "")
2153
2154 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "y", "y", "y", "y"])
2155 call VerifyBoth(buf, "Test_diff_overlapped_3.14", "")
2156
2157 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "b", "y", "d", "e"])
2158 call VerifyBoth(buf, "Test_diff_overlapped_3.15", "")
2159
2160 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "b", "y", "y", "e"])
2161 call VerifyBoth(buf, "Test_diff_overlapped_3.16", "")
2162
2163 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "b", "y", "y", "y"])
2164 call VerifyBoth(buf, "Test_diff_overlapped_3.17", "")
2165
2166 call WriteDiffFiles3(buf, ["a", "b"], ["x", "b"], ["y", "y"])
2167 call writefile(["a", "b"], "Xdiin1")
2168 call writefile(["x", "b"], "Xdinew1")
2169 call writefile(["1c1"], "Xdiout1")
2170 call writefile(["a", "b"], "Xdiin2")
2171 call writefile(["y", "y"], "Xdinew2")
2172 call writefile(["1c1", "2c2"], "Xdiout2")
2173 call term_sendkeys(buf, ":set diffexpr=DiffExprStub()\<CR>:")
2174 call VerifyInternal(buf, "Test_diff_overlapped_3.18", "")
2175 call term_sendkeys(buf, ":set diffexpr&\<CR>:")
2176
2177 call WriteDiffFiles3(buf, ["a", "b", "c", "d"], ["x", "b", "x", "d"], ["y", "y", "c", "d"])
2178 call writefile(["a", "b", "c", "d"], "Xdiin1")
2179 call writefile(["x", "b", "x", "d"], "Xdinew1")
2180 call writefile(["1c1", "3c3"], "Xdiout1")
2181 call writefile(["a", "b", "c", "d"], "Xdiin2")
2182 call writefile(["y", "y", "c", "d"], "Xdinew2")
2183 call writefile(["1c1", "2c2"], "Xdiout2")
2184 call term_sendkeys(buf, ":set diffexpr=DiffExprStub()\<CR>:")
2185 call VerifyInternal(buf, "Test_diff_overlapped_3.19", "")
2186 call term_sendkeys(buf, ":set diffexpr&\<CR>:")
2187
2188 call WriteDiffFiles3(buf, ["a", "b", "c", "d"], ["x", "b", "x", "d"], ["y", "y", "y", "d"])
2189 call writefile(["a", "b", "c", "d"], "Xdiin1")
2190 call writefile(["x", "b", "x", "d"], "Xdinew1")
2191 call writefile(["1c1", "3c3"], "Xdiout1")
2192 call writefile(["a", "b", "c", "d"], "Xdiin2")
2193 call writefile(["y", "y", "y", "d"], "Xdinew2")
2194 call writefile(["1c1", "2,3c2,3"], "Xdiout2")
2195 call term_sendkeys(buf, ":set diffexpr=DiffExprStub()\<CR>:")
2196 call VerifyInternal(buf, "Test_diff_overlapped_3.20", "")
2197 call term_sendkeys(buf, ":set diffexpr&\<CR>:")
2198
2199 call WriteDiffFiles3(buf, ["a", "b", "c", "d"], ["x", "b", "x", "d"], ["y", "y", "y", "y"])
2200 call writefile(["a", "b", "c", "d"], "Xdiin1")
2201 call writefile(["x", "b", "x", "d"], "Xdinew1")
2202 call writefile(["1c1", "3c3"], "Xdiout1")
2203 call writefile(["a", "b", "c", "d"], "Xdiin2")
2204 call writefile(["y", "y", "y", "y"], "Xdinew2")
2205 call writefile(["1c1", "2,4c2,4"], "Xdiout2")
2206 call term_sendkeys(buf, ":set diffexpr=DiffExprStub()\<CR>:")
2207 call VerifyInternal(buf, "Test_diff_overlapped_3.21", "")
2208 call term_sendkeys(buf, ":set diffexpr&\<CR>:")
2209
2210 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["b", "c"])
2211 call VerifyBoth(buf, "Test_diff_overlapped_3.22", "")
2212
2213 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["c"])
2214 call VerifyBoth(buf, "Test_diff_overlapped_3.23", "")
2215
2216 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], [])
2217 call VerifyBoth(buf, "Test_diff_overlapped_3.24", "")
2218
2219 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["a", "c"])
2220 call VerifyBoth(buf, "Test_diff_overlapped_3.25", "")
2221
2222 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["a"])
2223 call VerifyBoth(buf, "Test_diff_overlapped_3.26", "")
2224
2225 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["b"])
2226 call VerifyBoth(buf, "Test_diff_overlapped_3.27", "")
2227
2228 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["d", "e"])
2229 call VerifyBoth(buf, "Test_diff_overlapped_3.28", "")
2230
2231 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["e"])
2232 call VerifyBoth(buf, "Test_diff_overlapped_3.29", "")
2233
2234 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "d", "e"])
2235 call VerifyBoth(buf, "Test_diff_overlapped_3.30", "")
2236
2237 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "e"])
2238 call VerifyBoth(buf, "Test_diff_overlapped_3.31", "")
2239
2240 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a"])
2241 call VerifyBoth(buf, "Test_diff_overlapped_3.32", "")
2242
2243 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "b", "d", "e"])
2244 call VerifyBoth(buf, "Test_diff_overlapped_3.33", "")
2245
2246 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "b", "e"])
2247 call VerifyBoth(buf, "Test_diff_overlapped_3.34", "")
2248
2249 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "b"])
2250 call VerifyBoth(buf, "Test_diff_overlapped_3.35", "")
2251
2252 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["a", "y", "b", "c"])
2253 call VerifyBoth(buf, "Test_diff_overlapped_3.36", "")
2254
2255 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["a", "b", "y", "c"])
2256 call VerifyBoth(buf, "Test_diff_overlapped_3.37", "")
2257
2258 call StopVimInTerminal(buf)
2259endfunc
2260
Bram Moolenaar8dfcce32020-03-18 19:32:26 +01002261" vim: shiftwidth=2 sts=2 expandtab