blob: d0c2f18e4ee8cfba9c032cb3dfe01540a7e85b7d [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
Yee Cheng Chin9943d472025-03-26 19:41:02 +0100433 call setline(1, ['One', 'Two', 'Three', 'Four', 'Fi#vϵ', 'Si⃗x', 'Se⃗ve⃗n'])
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200434 redraw
435 let normattr = screenattr(1, 1)
436 diffthis
437
438 botright vert new two
Yee Cheng Chin9943d472025-03-26 19:41:02 +0100439 call setline(1, ['one', 'TWO', 'Three ', 'Four', 'fI=VΕ', 'SI⃗x', 'SEvE⃗n'])
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))
Yee Cheng Chin9943d472025-03-26 19:41:02 +0100447 call assert_equal(normattr, screenattr(6, 2))
448 call assert_notequal(normattr, screenattr(7, 2))
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200449
Bram Moolenaarda22b8c2017-09-02 18:01:50 +0200450 let dtextattr = screenattr(5, 3)
451 call assert_notequal(dtextattr, screenattr(5, 1))
452 call assert_notequal(dtextattr, screenattr(5, 5))
Yee Cheng Chin9943d472025-03-26 19:41:02 +0100453 call assert_notequal(dtextattr, screenattr(7, 4))
Bram Moolenaarda22b8c2017-09-02 18:01:50 +0200454
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200455 diffoff!
456 %bwipe!
Bram Moolenaare828b762018-09-10 17:51:58 +0200457endfunc
458
459func Test_diffopt_icase()
460 set diffopt=icase,foldcolumn:0
461 call Common_icase_test()
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200462 set diffopt&
463endfunc
464
Bram Moolenaare828b762018-09-10 17:51:58 +0200465func Test_diffopt_icase_internal()
466 set diffopt=icase,foldcolumn:0,internal
467 call Common_icase_test()
468 set diffopt&
469endfunc
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200470
Bram Moolenaare828b762018-09-10 17:51:58 +0200471func Common_iwhite_test()
472 edit one
473 " Difference in trailing spaces and amount of spaces should be ignored,
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200474 " but not other space differences.
Bram Moolenaare828b762018-09-10 17:51:58 +0200475 call setline(1, ["One \t", 'Two', 'Three', 'one two', 'one two', 'Four'])
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200476 redraw
477 let normattr = screenattr(1, 1)
478 diffthis
479
480 botright vert new two
Bram Moolenaare828b762018-09-10 17:51:58 +0200481 call setline(1, ["One\t ", "Two\t ", 'Three', 'one two', 'onetwo', ' Four'])
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200482 diffthis
483
484 redraw
485 call assert_equal(normattr, screenattr(1, 1))
486 call assert_equal(normattr, screenattr(2, 1))
487 call assert_equal(normattr, screenattr(3, 1))
Bram Moolenaare828b762018-09-10 17:51:58 +0200488 call assert_equal(normattr, screenattr(4, 1))
489 call assert_notequal(normattr, screenattr(5, 1))
490 call assert_notequal(normattr, screenattr(6, 1))
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200491
492 diffoff!
493 %bwipe!
Bram Moolenaare828b762018-09-10 17:51:58 +0200494endfunc
495
496func Test_diffopt_iwhite()
497 set diffopt=iwhite,foldcolumn:0
498 call Common_iwhite_test()
499 set diffopt&
500endfunc
501
502func Test_diffopt_iwhite_internal()
503 set diffopt=internal,iwhite,foldcolumn:0
504 call Common_iwhite_test()
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200505 set diffopt&
506endfunc
507
508func Test_diffopt_context()
509 enew!
510 call setline(1, ['1', '2', '3', '4', '5', '6', '7'])
511 diffthis
512 new
513 call setline(1, ['1', '2', '3', '4', '5x', '6', '7'])
514 diffthis
515
516 set diffopt=context:2
517 call assert_equal('+-- 2 lines: 1', foldtextresult(1))
Bram Moolenaare828b762018-09-10 17:51:58 +0200518 set diffopt=internal,context:2
519 call assert_equal('+-- 2 lines: 1', foldtextresult(1))
520
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200521 set diffopt=context:1
522 call assert_equal('+-- 3 lines: 1', foldtextresult(1))
Bram Moolenaare828b762018-09-10 17:51:58 +0200523 set diffopt=internal,context:1
524 call assert_equal('+-- 3 lines: 1', foldtextresult(1))
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200525
526 diffoff!
527 %bwipe!
528 set diffopt&
529endfunc
530
531func Test_diffopt_horizontal()
Bram Moolenaare828b762018-09-10 17:51:58 +0200532 set diffopt=internal,horizontal
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200533 diffsplit
534
535 call assert_equal(&columns, winwidth(1))
536 call assert_equal(&columns, winwidth(2))
537 call assert_equal(&lines, winheight(1) + winheight(2) + 3)
538 call assert_inrange(0, 1, winheight(1) - winheight(2))
539
540 set diffopt&
541 diffoff!
542 %bwipe
543endfunc
544
545func Test_diffopt_vertical()
Bram Moolenaare828b762018-09-10 17:51:58 +0200546 set diffopt=internal,vertical
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200547 diffsplit
548
549 call assert_equal(&lines - 2, winheight(1))
550 call assert_equal(&lines - 2, winheight(2))
551 call assert_equal(&columns, winwidth(1) + winwidth(2) + 1)
552 call assert_inrange(0, 1, winwidth(1) - winwidth(2))
553
554 set diffopt&
555 diffoff!
556 %bwipe
557endfunc
558
Bram Moolenaar97ce4192017-12-01 20:35:58 +0100559func Test_diffopt_hiddenoff()
Bram Moolenaare828b762018-09-10 17:51:58 +0200560 set diffopt=internal,filler,foldcolumn:0,hiddenoff
Bram Moolenaar97ce4192017-12-01 20:35:58 +0100561 e! one
562 call setline(1, ['Two', 'Three'])
563 redraw
564 let normattr = screenattr(1, 1)
565 diffthis
566 botright vert new two
567 call setline(1, ['One', 'Four'])
568 diffthis
569 redraw
570 call assert_notequal(normattr, screenattr(1, 1))
571 set hidden
572 close
573 redraw
574 " should not diffing with hidden buffer two while 'hiddenoff' is enabled
575 call assert_equal(normattr, screenattr(1, 1))
576
577 bwipe!
578 bwipe!
579 set hidden& diffopt&
580endfunc
581
Bram Moolenaar25ea0542017-02-03 23:16:28 +0100582func Test_diffoff_hidden()
Bram Moolenaare828b762018-09-10 17:51:58 +0200583 set diffopt=internal,filler,foldcolumn:0
Bram Moolenaar25ea0542017-02-03 23:16:28 +0100584 e! one
585 call setline(1, ['Two', 'Three'])
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200586 redraw
Bram Moolenaar25ea0542017-02-03 23:16:28 +0100587 let normattr = screenattr(1, 1)
588 diffthis
589 botright vert new two
590 call setline(1, ['One', 'Four'])
591 diffthis
592 redraw
593 call assert_notequal(normattr, screenattr(1, 1))
594 set hidden
595 close
596 redraw
597 " diffing with hidden buffer two
598 call assert_notequal(normattr, screenattr(1, 1))
599 diffoff
600 redraw
601 call assert_equal(normattr, screenattr(1, 1))
602 diffthis
603 redraw
604 " still diffing with hidden buffer two
605 call assert_notequal(normattr, screenattr(1, 1))
606 diffoff!
607 redraw
608 call assert_equal(normattr, screenattr(1, 1))
609 diffthis
610 redraw
611 " no longer diffing with hidden buffer two
612 call assert_equal(normattr, screenattr(1, 1))
613
614 bwipe!
615 bwipe!
616 set hidden& diffopt&
617endfunc
618
Bram Moolenaar025e3e02016-10-18 14:50:18 +0200619func Test_setting_cursor()
620 new Xtest1
621 put =range(1,90)
622 wq
623 new Xtest2
624 put =range(1,100)
625 wq
Bram Moolenaar97fbc402017-09-26 19:41:46 +0200626
Bram Moolenaar025e3e02016-10-18 14:50:18 +0200627 tabe Xtest2
628 $
629 diffsp Xtest1
630 tabclose
631
632 call delete('Xtest1')
633 call delete('Xtest2')
634endfunc
Bram Moolenaaraeb661e2017-02-26 19:59:59 +0100635
636func Test_diff_move_to()
637 new
638 call setline(1, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
639 diffthis
640 vnew
641 call setline(1, [1, '2x', 3, 4, 4, 5, '6x', 7, '8x', 9, '10x'])
642 diffthis
643 norm ]c
644 call assert_equal(2, line('.'))
645 norm 3]c
646 call assert_equal(9, line('.'))
647 norm 10]c
648 call assert_equal(11, line('.'))
649 norm [c
650 call assert_equal(9, line('.'))
651 norm 2[c
652 call assert_equal(5, line('.'))
653 norm 10[c
654 call assert_equal(2, line('.'))
655 %bwipe!
656endfunc
657
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200658func Test_diffexpr()
Bram Moolenaaraeb313f2020-11-27 19:13:28 +0100659 CheckExecutable diff
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200660
661 func DiffExpr()
Bram Moolenaar485b6272021-05-18 19:19:03 +0200662 " Prepend some text to check diff type detection
Bram Moolenaar3b8defd2018-09-13 13:03:11 +0200663 call writefile(['warning', ' message'], v:fname_out)
664 silent exe '!diff ' . v:fname_in . ' ' . v:fname_new . '>>' . v:fname_out
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200665 endfunc
666 set diffexpr=DiffExpr()
667 set diffopt=foldcolumn:0
668
669 enew!
670 call setline(1, ['one', 'two', 'three'])
671 redraw
672 let normattr = screenattr(1, 1)
673 diffthis
674
675 botright vert new
676 call setline(1, ['one', 'two', 'three.'])
677 diffthis
678
679 redraw
680 call assert_equal(normattr, screenattr(1, 1))
681 call assert_equal(normattr, screenattr(2, 1))
682 call assert_notequal(normattr, screenattr(3, 1))
Yegappan Lakshmanan30443242021-06-10 21:52:15 +0200683 diffoff!
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200684
Dominique Pelle923dce22021-11-21 11:36:04 +0000685 " Try using a non-existing function for 'diffexpr'.
Yegappan Lakshmanan30443242021-06-10 21:52:15 +0200686 set diffexpr=NewDiffFunc()
687 call assert_fails('windo diffthis', ['E117:', 'E97:'])
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200688 diffoff!
Yegappan Lakshmanan8bb65f22021-12-26 10:51:39 +0000689
690 " Using a script-local function
691 func s:NewDiffExpr()
692 endfunc
693 set diffexpr=s:NewDiffExpr()
694 call assert_equal(expand('<SID>') .. 'NewDiffExpr()', &diffexpr)
695 set diffexpr=<SID>NewDiffExpr()
696 call assert_equal(expand('<SID>') .. 'NewDiffExpr()', &diffexpr)
697
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200698 %bwipe!
699 set diffexpr& diffopt&
Yegappan Lakshmanan8bb65f22021-12-26 10:51:39 +0000700 delfunc DiffExpr
701 delfunc s:NewDiffExpr
Bram Moolenaar79a213d2017-05-16 13:15:18 +0200702endfunc
703
Bram Moolenaaraeb661e2017-02-26 19:59:59 +0100704func Test_diffpatch()
705 " The patch program on MS-Windows may fail or hang.
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200706 CheckExecutable patch
707 CheckUnix
Bram Moolenaaraeb661e2017-02-26 19:59:59 +0100708 new
709 insert
710***************
711*** 1,3 ****
712 1
713! 2
714 3
715--- 1,4 ----
716 1
717! 2x
718 3
719+ 4
720.
Bram Moolenaar97fbc402017-09-26 19:41:46 +0200721 saveas! Xpatch
Bram Moolenaaraeb661e2017-02-26 19:59:59 +0100722 bwipe!
723 new
724 call assert_fails('diffpatch Xpatch', 'E816:')
Bram Moolenaar1ef73e32017-03-09 19:21:30 +0100725
Bram Moolenaara95ab322017-03-11 19:21:53 +0100726 for name in ['Xpatch', 'Xpatch$HOME', 'Xpa''tch']
Bram Moolenaar1ef73e32017-03-09 19:21:30 +0100727 call setline(1, ['1', '2', '3'])
728 if name != 'Xpatch'
729 call rename('Xpatch', name)
730 endif
731 exe 'diffpatch ' . escape(name, '$')
732 call assert_equal(['1', '2x', '3', '4'], getline(1, '$'))
733 if name != 'Xpatch'
734 call rename(name, 'Xpatch')
735 endif
736 bwipe!
737 endfor
738
Bram Moolenaaraeb661e2017-02-26 19:59:59 +0100739 call delete('Xpatch')
740 bwipe!
741endfunc
742
Bram Moolenaar23a971d2023-04-04 22:04:53 +0100743" FIXME: test fails, the Xresult file can't be read
744func No_Test_diffpatch_restricted()
745 let lines =<< trim END
746 call assert_fails('diffpatch NoSuchDiff', 'E145:')
747
748 call writefile(v:errors, 'Xresult')
749 qa!
750 END
751 call writefile(lines, 'Xrestricted', 'D')
752 if RunVim([], [], '-Z --clean -S Xrestricted')
753 call assert_equal([], readfile('Xresult'))
754 endif
755 call delete('Xresult')
756endfunc
757
Bram Moolenaaraeb661e2017-02-26 19:59:59 +0100758func Test_diff_too_many_buffers()
759 for i in range(1, 8)
760 exe "new Xtest" . i
761 diffthis
762 endfor
763 new Xtest9
764 call assert_fails('diffthis', 'E96:')
765 %bwipe!
766endfunc
767
768func Test_diff_nomodifiable()
769 new
770 call setline(1, [1, 2, 3, 4])
771 setl nomodifiable
772 diffthis
773 vnew
774 call setline(1, ['1x', 2, 3, 3, 4])
775 diffthis
776 call assert_fails('norm dp', 'E793:')
777 setl nomodifiable
778 call assert_fails('norm do', 'E21:')
779 %bwipe!
780endfunc
Bram Moolenaarf58a8472017-03-05 18:03:04 +0100781
Bram Moolenaar97fbc402017-09-26 19:41:46 +0200782func Test_diff_hlID()
783 new
Yee Cheng Chin9943d472025-03-26 19:41:02 +0100784 call setline(1, [1, 2, 3, 'Yz', 'a dxxg',])
Bram Moolenaar97fbc402017-09-26 19:41:46 +0200785 diffthis
786 vnew
Yee Cheng Chin9943d472025-03-26 19:41:02 +0100787 call setline(1, ['1x', 2, 'x', 3, 'yx', 'abc defg'])
Bram Moolenaar97fbc402017-09-26 19:41:46 +0200788 diffthis
789 redraw
790
Bram Moolenaara74e4942019-08-04 17:35:53 +0200791 call diff_hlID(-1, 1)->synIDattr("name")->assert_equal("")
Bram Moolenaar97fbc402017-09-26 19:41:46 +0200792
Bram Moolenaara74e4942019-08-04 17:35:53 +0200793 call diff_hlID(1, 1)->synIDattr("name")->assert_equal("DiffChange")
794 call diff_hlID(1, 2)->synIDattr("name")->assert_equal("DiffText")
795 call diff_hlID(2, 1)->synIDattr("name")->assert_equal("")
796 call diff_hlID(3, 1)->synIDattr("name")->assert_equal("DiffAdd")
Bram Moolenaar1a3a8912019-08-23 22:31:37 +0200797 eval 4->diff_hlID(1)->synIDattr("name")->assert_equal("")
Yee Cheng Chin9943d472025-03-26 19:41:02 +0100798 call diff_hlID(5, 1)->synIDattr("name")->assert_equal("DiffText")
799 call diff_hlID(5, 2)->synIDattr("name")->assert_equal("DiffText")
800
801 set diffopt+=icase " test that caching is invalidated by diffopt change
802 call diff_hlID(5, 1)->synIDattr("name")->assert_equal("DiffChange")
803 set diffopt-=icase
804 call diff_hlID(5, 1)->synIDattr("name")->assert_equal("DiffText")
805
806 call diff_hlID(6, 1)->synIDattr("name")->assert_equal("DiffChange")
807 call diff_hlID(6, 2)->synIDattr("name")->assert_equal("DiffText")
808 call diff_hlID(6, 4)->synIDattr("name")->assert_equal("DiffText")
809 call diff_hlID(6, 7)->synIDattr("name")->assert_equal("DiffText")
810 call diff_hlID(6, 8)->synIDattr("name")->assert_equal("DiffChange")
811 set diffopt+=inline:char
812 call diff_hlID(6, 1)->synIDattr("name")->assert_equal("DiffChange")
813 call diff_hlID(6, 2)->synIDattr("name")->assert_equal("DiffTextAdd")
814 call diff_hlID(6, 4)->synIDattr("name")->assert_equal("DiffChange")
815 call diff_hlID(6, 7)->synIDattr("name")->assert_equal("DiffText")
816 call diff_hlID(6, 8)->synIDattr("name")->assert_equal("DiffChange")
817 set diffopt-=inline:char
Bram Moolenaar97fbc402017-09-26 19:41:46 +0200818
819 wincmd w
820 call assert_equal(synIDattr(diff_hlID(1, 1), "name"), "DiffChange")
821 call assert_equal(synIDattr(diff_hlID(2, 1), "name"), "")
822 call assert_equal(synIDattr(diff_hlID(3, 1), "name"), "")
823
824 %bwipe!
825endfunc
826
827func Test_diff_filler()
828 new
829 call setline(1, [1, 2, 3, 'x', 4])
830 diffthis
831 vnew
832 call setline(1, [1, 2, 'y', 'y', 3, 4])
833 diffthis
834 redraw
835
Bram Moolenaar1a3a8912019-08-23 22:31:37 +0200836 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 +0200837 wincmd w
838 call assert_equal([0, 0, 0, 0, 2, 0, 0, 0], map(range(-1, 6), 'diff_filler(v:val)'))
839
840 %bwipe!
841endfunc
842
Bram Moolenaarf58a8472017-03-05 18:03:04 +0100843func Test_diff_lastline()
844 enew!
845 only!
846 call setline(1, ['This is a ', 'line with five ', 'rows'])
847 diffthis
848 botright vert new
849 call setline(1, ['This is', 'a line with ', 'four rows'])
850 diffthis
851 1
852 call feedkeys("Je a\<CR>", 'tx')
853 call feedkeys("Je a\<CR>", 'tx')
854 let w1lines = winline()
855 wincmd w
856 $
857 let w2lines = winline()
858 call assert_equal(w2lines, w1lines)
859 bwipe!
860 bwipe!
861endfunc
Bram Moolenaare828b762018-09-10 17:51:58 +0200862
Bram Moolenaar785fc652018-09-15 19:17:38 +0200863func WriteDiffFiles(buf, list1, list2)
Bram Moolenaar61abe7d2022-08-30 21:46:08 +0100864 call writefile(a:list1, 'Xdifile1')
865 call writefile(a:list2, 'Xdifile2')
Bram Moolenaar785fc652018-09-15 19:17:38 +0200866 if a:buf
867 call term_sendkeys(a:buf, ":checktime\<CR>")
868 endif
Bram Moolenaare828b762018-09-10 17:51:58 +0200869endfunc
870
Yukihiro Nakadaira06fe70c2024-09-26 16:19:42 +0200871func WriteDiffFiles3(buf, list1, list2, list3)
872 call writefile(a:list1, 'Xdifile1')
873 call writefile(a:list2, 'Xdifile2')
874 call writefile(a:list3, 'Xdifile3')
875 if a:buf
876 call term_sendkeys(a:buf, ":checktime\<CR>")
877 endif
878endfunc
879
Bram Moolenaar785fc652018-09-15 19:17:38 +0200880" Verify a screendump with both the internal and external diff.
Bram Moolenaare828b762018-09-10 17:51:58 +0200881func VerifyBoth(buf, dumpfile, extra)
Bram Moolenaare828b762018-09-10 17:51:58 +0200882 " trailing : for leaving the cursor on the command line
Bram Moolenaar785fc652018-09-15 19:17:38 +0200883 for cmd in [":set diffopt=filler" . a:extra . "\<CR>:", ":set diffopt+=internal\<CR>:"]
Bram Moolenaare828b762018-09-10 17:51:58 +0200884 call term_sendkeys(a:buf, cmd)
885 if VerifyScreenDump(a:buf, a:dumpfile, {}, cmd =~ 'internal' ? 'internal' : 'external')
Bram Moolenaar485b6272021-05-18 19:19:03 +0200886 " don't let the next iteration overwrite the "failed" file.
887 return
Bram Moolenaare828b762018-09-10 17:51:58 +0200888 endif
889 endfor
Bram Moolenaar485b6272021-05-18 19:19:03 +0200890
891 " also test unified diff
892 call term_sendkeys(a:buf, ":call SetupUnified()\<CR>:")
glacambread5c1782021-05-24 14:20:53 +0200893 call term_sendkeys(a:buf, ":redraw!\<CR>:")
Bram Moolenaar485b6272021-05-18 19:19:03 +0200894 call VerifyScreenDump(a:buf, a:dumpfile, {}, 'unified')
895 call term_sendkeys(a:buf, ":call StopUnified()\<CR>:")
Bram Moolenaare828b762018-09-10 17:51:58 +0200896endfunc
897
Bram Moolenaar785fc652018-09-15 19:17:38 +0200898" Verify a screendump with the internal diff only.
899func VerifyInternal(buf, dumpfile, extra)
900 call term_sendkeys(a:buf, ":diffupdate!\<CR>")
901 " trailing : for leaving the cursor on the command line
902 call term_sendkeys(a:buf, ":set diffopt=internal,filler" . a:extra . "\<CR>:")
903 call VerifyScreenDump(a:buf, a:dumpfile, {})
904endfunc
905
Bram Moolenaare828b762018-09-10 17:51:58 +0200906func Test_diff_screen()
Yee Cheng Chin49f2ba62024-02-14 20:34:58 +0100907 if has('osxdarwin') && system('diff --version') =~ '^Apple diff'
908 throw 'Skipped: unified diff does not work properly on this macOS version'
rhysde93d5ca2024-02-01 21:22:14 +0100909 endif
910
Bram Moolenaarf08b0eb2021-10-16 13:00:14 +0100911 let g:test_is_flaky = 1
Bram Moolenaar3c8ee622019-08-03 22:55:50 +0200912 CheckScreendump
913 CheckFeature menu
914
Bram Moolenaar485b6272021-05-18 19:19:03 +0200915 let lines =<< trim END
916 func UnifiedDiffExpr()
917 " Prepend some text to check diff type detection
918 call writefile(['warning', ' message'], v:fname_out)
glacambread5c1782021-05-24 14:20:53 +0200919 silent exe '!diff -U0 ' .. v:fname_in .. ' ' .. v:fname_new .. '>>' .. v:fname_out
Bram Moolenaar485b6272021-05-18 19:19:03 +0200920 endfunc
921 func SetupUnified()
922 set diffexpr=UnifiedDiffExpr()
glacambread5c1782021-05-24 14:20:53 +0200923 diffupdate
Bram Moolenaar485b6272021-05-18 19:19:03 +0200924 endfunc
925 func StopUnified()
926 set diffexpr=
927 endfunc
928 END
Bram Moolenaar59173412022-09-20 22:01:33 +0100929 call writefile(lines, 'XdiffSetup', 'D')
Bram Moolenaar485b6272021-05-18 19:19:03 +0200930
Bram Moolenaare828b762018-09-10 17:51:58 +0200931 " clean up already existing swap files, just in case
Bram Moolenaar61abe7d2022-08-30 21:46:08 +0100932 call delete('.Xdifile1.swp')
933 call delete('.Xdifile2.swp')
Bram Moolenaare828b762018-09-10 17:51:58 +0200934
935 " Test 1: Add a line in beginning of file 2
Bram Moolenaar785fc652018-09-15 19:17:38 +0200936 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 +0100937 let buf = RunVimInTerminal('-d -S XdiffSetup Xdifile1 Xdifile2', {})
Bram Moolenaar8ee4c012019-03-29 18:08:18 +0100938 " Set autoread mode, so that Vim won't complain once we re-write the test
Bram Moolenaare828b762018-09-10 17:51:58 +0200939 " files
Bram Moolenaar785fc652018-09-15 19:17:38 +0200940 call term_sendkeys(buf, ":set autoread\<CR>\<c-w>w:set autoread\<CR>\<c-w>w")
Bram Moolenaare828b762018-09-10 17:51:58 +0200941
942 call VerifyBoth(buf, 'Test_diff_01', '')
943
944 " Test 2: Add a line in beginning of file 1
Bram Moolenaar785fc652018-09-15 19:17:38 +0200945 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 +0200946 call VerifyBoth(buf, 'Test_diff_02', '')
947
948 " Test 3: Add a line at the end of file 2
Bram Moolenaar785fc652018-09-15 19:17:38 +0200949 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 +0200950 call VerifyBoth(buf, 'Test_diff_03', '')
951
952 " Test 4: Add a line at the end of file 1
Bram Moolenaar785fc652018-09-15 19:17:38 +0200953 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 +0200954 call VerifyBoth(buf, 'Test_diff_04', '')
955
956 " 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 +0200957 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 +0200958 call VerifyBoth(buf, 'Test_diff_05', '')
959
960 " 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 +0200961 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 +0200962 call VerifyBoth(buf, 'Test_diff_06', '')
963
Bram Moolenaarb9ddda62019-02-19 23:00:50 +0100964 " Variants on test 6 with different context settings
965 call term_sendkeys(buf, ":set diffopt+=context:2\<cr>")
966 call VerifyScreenDump(buf, 'Test_diff_06.2', {})
967 call term_sendkeys(buf, ":set diffopt-=context:2\<cr>")
968 call term_sendkeys(buf, ":set diffopt+=context:1\<cr>")
969 call VerifyScreenDump(buf, 'Test_diff_06.1', {})
970 call term_sendkeys(buf, ":set diffopt-=context:1\<cr>")
971 call term_sendkeys(buf, ":set diffopt+=context:0\<cr>")
972 call VerifyScreenDump(buf, 'Test_diff_06.0', {})
973 call term_sendkeys(buf, ":set diffopt-=context:0\<cr>")
974
Bram Moolenaare828b762018-09-10 17:51:58 +0200975 " Test 7 - 9: Test normal/patience/histogram diff algorithm
Bram Moolenaar785fc652018-09-15 19:17:38 +0200976 call WriteDiffFiles(buf, ['#include <stdio.h>', '', '// Frobs foo heartily', 'int frobnitz(int foo)', '{',
Bram Moolenaare828b762018-09-10 17:51:58 +0200977 \ ' int i;', ' for(i = 0; i < 10; i++)', ' {', ' printf("Your answer is: ");',
978 \ ' printf("%d\n", foo);', ' }', '}', '', 'int fact(int n)', '{', ' if(n > 1)', ' {',
979 \ ' return fact(n-1) * n;', ' }', ' return 1;', '}', '', 'int main(int argc, char **argv)',
980 \ '{', ' frobnitz(fact(10));', '}'],
981 \ ['#include <stdio.h>', '', 'int fib(int n)', '{', ' if(n > 2)', ' {',
982 \ ' return fib(n-1) + fib(n-2);', ' }', ' return 1;', '}', '', '// Frobs foo heartily',
983 \ 'int frobnitz(int foo)', '{', ' int i;', ' for(i = 0; i < 10; i++)', ' {',
984 \ ' printf("%d\n", foo);', ' }', '}', '',
985 \ 'int main(int argc, char **argv)', '{', ' frobnitz(fib(10));', '}'])
986 call term_sendkeys(buf, ":diffupdate!\<cr>")
987 call term_sendkeys(buf, ":set diffopt+=internal\<cr>")
988 call VerifyScreenDump(buf, 'Test_diff_07', {})
989
990 call term_sendkeys(buf, ":set diffopt+=algorithm:patience\<cr>")
991 call VerifyScreenDump(buf, 'Test_diff_08', {})
992
993 call term_sendkeys(buf, ":set diffopt+=algorithm:histogram\<cr>")
994 call VerifyScreenDump(buf, 'Test_diff_09', {})
995
996 " Test 10-11: normal/indent-heuristic
997 call term_sendkeys(buf, ":set diffopt&vim\<cr>")
Bram Moolenaar785fc652018-09-15 19:17:38 +0200998 call WriteDiffFiles(buf, ['', ' def finalize(values)', '', ' values.each do |v|', ' v.finalize', ' end'],
Bram Moolenaare828b762018-09-10 17:51:58 +0200999 \ ['', ' def finalize(values)', '', ' values.each do |v|', ' v.prepare', ' end', '',
1000 \ ' values.each do |v|', ' v.finalize', ' end'])
1001 call term_sendkeys(buf, ":diffupdate!\<cr>")
1002 call term_sendkeys(buf, ":set diffopt+=internal\<cr>")
1003 call VerifyScreenDump(buf, 'Test_diff_10', {})
1004
Bram Moolenaarb6fc7282018-12-04 22:24:16 +01001005 " Leave trailing : at commandline!
1006 call term_sendkeys(buf, ":set diffopt+=indent-heuristic\<cr>:\<cr>")
1007 call VerifyScreenDump(buf, 'Test_diff_11', {}, 'one')
1008 " shouldn't matter, if indent-algorithm comes before or after the algorithm
1009 call term_sendkeys(buf, ":set diffopt&\<cr>")
1010 call term_sendkeys(buf, ":set diffopt+=indent-heuristic,algorithm:patience\<cr>:\<cr>")
1011 call VerifyScreenDump(buf, 'Test_diff_11', {}, 'two')
1012 call term_sendkeys(buf, ":set diffopt&\<cr>")
1013 call term_sendkeys(buf, ":set diffopt+=algorithm:patience,indent-heuristic\<cr>:\<cr>")
1014 call VerifyScreenDump(buf, 'Test_diff_11', {}, 'three')
Bram Moolenaare828b762018-09-10 17:51:58 +02001015
1016 " Test 12: diff the same file
Bram Moolenaar785fc652018-09-15 19:17:38 +02001017 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 +02001018 call VerifyBoth(buf, 'Test_diff_12', '')
1019
1020 " Test 13: diff an empty file
Bram Moolenaar785fc652018-09-15 19:17:38 +02001021 call WriteDiffFiles(buf, [], [])
Bram Moolenaare828b762018-09-10 17:51:58 +02001022 call VerifyBoth(buf, 'Test_diff_13', '')
1023
1024 " Test 14: test diffopt+=icase
Bram Moolenaar785fc652018-09-15 19:17:38 +02001025 call WriteDiffFiles(buf, ['a', 'b', 'cd'], ['A', 'b', 'cDe'])
Bram Moolenaare828b762018-09-10 17:51:58 +02001026 call VerifyBoth(buf, 'Test_diff_14', " diffopt+=filler diffopt+=icase")
1027
1028 " Test 15-16: test diffopt+=iwhite
Bram Moolenaar785fc652018-09-15 19:17:38 +02001029 call WriteDiffFiles(buf, ['int main()', '{', ' printf("Hello, World!");', ' return 0;', '}'],
Bram Moolenaare828b762018-09-10 17:51:58 +02001030 \ ['int main()', '{', ' if (0)', ' {', ' printf("Hello, World!");', ' return 0;', ' }', '}'])
1031 call term_sendkeys(buf, ":diffupdate!\<cr>")
1032 call term_sendkeys(buf, ":set diffopt&vim diffopt+=filler diffopt+=iwhite\<cr>")
1033 call VerifyScreenDump(buf, 'Test_diff_15', {})
1034 call term_sendkeys(buf, ":set diffopt+=internal\<cr>")
1035 call VerifyScreenDump(buf, 'Test_diff_16', {})
1036
Bram Moolenaar785fc652018-09-15 19:17:38 +02001037 " Test 17: test diffopt+=iblank
1038 call WriteDiffFiles(buf, ['a', ' ', 'cd', 'ef', 'xxx'], ['a', 'cd', '', 'ef', 'yyy'])
1039 call VerifyInternal(buf, 'Test_diff_17', " diffopt+=iblank")
1040
1041 " Test 18: test diffopt+=iblank,iwhite / iwhiteall / iwhiteeol
1042 call VerifyInternal(buf, 'Test_diff_18', " diffopt+=iblank,iwhite")
1043 call VerifyInternal(buf, 'Test_diff_18', " diffopt+=iblank,iwhiteall")
1044 call VerifyInternal(buf, 'Test_diff_18', " diffopt+=iblank,iwhiteeol")
1045
1046 " Test 19: test diffopt+=iwhiteeol
1047 call WriteDiffFiles(buf, ['a ', 'x', 'cd', 'ef', 'xx xx', 'foo', 'bar'], ['a', 'x', 'c d', ' ef', 'xx xx', 'foo', '', 'bar'])
1048 call VerifyInternal(buf, 'Test_diff_19', " diffopt+=iwhiteeol")
1049
Yukihiro Nakadairaf1694b42024-09-22 11:26:13 +02001050 " Test 20: test diffopt+=iwhiteall
Bram Moolenaar785fc652018-09-15 19:17:38 +02001051 call VerifyInternal(buf, 'Test_diff_20', " diffopt+=iwhiteall")
1052
Yukihiro Nakadairaf1694b42024-09-22 11:26:13 +02001053 " Test 21: Delete all lines
1054 call WriteDiffFiles(buf, [0], [])
1055 call VerifyBoth(buf, "Test_diff_21", "")
1056
1057 " Test 22: Add line to empty file
1058 call WriteDiffFiles(buf, [], [0])
1059 call VerifyBoth(buf, "Test_diff_22", "")
1060
Jonathon7c7a4e62025-01-12 09:58:00 +01001061 call WriteDiffFiles(buf, ['?a', '?b', '?c'], ['!b'])
1062 call VerifyInternal(buf, 'Test_diff_23', " diffopt+=linematch:30")
1063
1064 call WriteDiffFiles(buf, ['',
1065 \ 'common line',
1066 \ 'common line',
1067 \ '',
1068 \ 'DEFabc',
1069 \ 'xyz',
1070 \ 'xyz',
1071 \ 'xyz',
1072 \ 'DEFabc',
1073 \ 'DEFabc',
1074 \ 'DEFabc',
1075 \ 'common line',
1076 \ 'common line',
1077 \ 'DEF',
1078 \ 'common line',
1079 \ 'DEF',
1080 \ 'something' ],
1081 \ ['',
1082 \ 'common line',
1083 \ 'common line',
1084 \ '',
1085 \ 'ABCabc',
1086 \ 'ABCabc',
1087 \ 'ABCabc',
1088 \ 'ABCabc',
1089 \ 'common line',
1090 \ 'common line',
1091 \ 'common line',
1092 \ 'something'])
1093 call VerifyInternal(buf, 'Test_diff_24', " diffopt+=linematch:30")
1094
1095
Bram Moolenaare828b762018-09-10 17:51:58 +02001096 " clean up
1097 call StopVimInTerminal(buf)
Bram Moolenaar61abe7d2022-08-30 21:46:08 +01001098 call delete('Xdifile1')
1099 call delete('Xdifile2')
Bram Moolenaare828b762018-09-10 17:51:58 +02001100endfunc
1101
Bram Moolenaar04626c22021-09-01 16:02:07 +02001102func Test_diff_with_scroll_and_change()
1103 CheckScreendump
1104
1105 let lines =<< trim END
1106 call setline(1, range(1, 15))
1107 vnew
1108 call setline(1, range(9, 15))
1109 windo diffthis
1110 wincmd h
1111 exe "normal Gl5\<C-E>"
1112 END
Bram Moolenaar59173412022-09-20 22:01:33 +01001113 call writefile(lines, 'Xtest_scroll_change', 'D')
Bram Moolenaar04626c22021-09-01 16:02:07 +02001114 let buf = RunVimInTerminal('-S Xtest_scroll_change', {})
1115
1116 call VerifyScreenDump(buf, 'Test_diff_scroll_change_01', {})
1117
1118 call term_sendkeys(buf, "ax\<Esc>")
1119 call VerifyScreenDump(buf, 'Test_diff_scroll_change_02', {})
1120
Bram Moolenaar841c2252021-10-22 20:56:55 +01001121 call term_sendkeys(buf, "\<C-W>lay\<Esc>")
1122 call VerifyScreenDump(buf, 'Test_diff_scroll_change_03', {})
1123
Bram Moolenaar04626c22021-09-01 16:02:07 +02001124 " clean up
1125 call StopVimInTerminal(buf)
Bram Moolenaar04626c22021-09-01 16:02:07 +02001126endfunc
1127
Bram Moolenaar4a5abbd2018-10-02 18:26:10 +02001128func Test_diff_with_cursorline()
Bram Moolenaar3c8ee622019-08-03 22:55:50 +02001129 CheckScreendump
Bram Moolenaar4a5abbd2018-10-02 18:26:10 +02001130
1131 call writefile([
1132 \ 'hi CursorLine ctermbg=red ctermfg=white',
1133 \ 'set cursorline',
1134 \ 'call setline(1, ["foo","foo","foo","bar"])',
1135 \ 'vnew',
1136 \ 'call setline(1, ["bee","foo","foo","baz"])',
1137 \ 'windo diffthis',
1138 \ '2wincmd w',
Bram Moolenaar59173412022-09-20 22:01:33 +01001139 \ ], 'Xtest_diff_cursorline', 'D')
Bram Moolenaar4a5abbd2018-10-02 18:26:10 +02001140 let buf = RunVimInTerminal('-S Xtest_diff_cursorline', {})
1141
1142 call VerifyScreenDump(buf, 'Test_diff_with_cursorline_01', {})
1143 call term_sendkeys(buf, "j")
1144 call VerifyScreenDump(buf, 'Test_diff_with_cursorline_02', {})
1145 call term_sendkeys(buf, "j")
1146 call VerifyScreenDump(buf, 'Test_diff_with_cursorline_03', {})
1147
1148 " clean up
1149 call StopVimInTerminal(buf)
Bram Moolenaar4a5abbd2018-10-02 18:26:10 +02001150endfunc
Bram Moolenaarf7acf2b2018-11-01 21:14:53 +01001151
Bram Moolenaar127969c2022-03-06 19:54:13 +00001152func Test_diff_with_cursorline_number()
1153 CheckScreendump
1154
1155 let lines =<< trim END
1156 hi CursorLine ctermbg=red ctermfg=white
1157 hi CursorLineNr ctermbg=white ctermfg=black cterm=underline
1158 set cursorline number
1159 call setline(1, ["baz", "foo", "foo", "bar"])
1160 2
1161 vnew
1162 call setline(1, ["foo", "foo", "bar"])
1163 windo diffthis
1164 1wincmd w
1165 END
Bram Moolenaar59173412022-09-20 22:01:33 +01001166 call writefile(lines, 'Xtest_diff_cursorline_number', 'D')
Bram Moolenaar127969c2022-03-06 19:54:13 +00001167 let buf = RunVimInTerminal('-S Xtest_diff_cursorline_number', {})
1168
1169 call VerifyScreenDump(buf, 'Test_diff_with_cursorline_number_01', {})
1170 call term_sendkeys(buf, ":set cursorlineopt=number\r")
1171 call VerifyScreenDump(buf, 'Test_diff_with_cursorline_number_02', {})
1172
1173 " clean up
1174 call StopVimInTerminal(buf)
Bram Moolenaar127969c2022-03-06 19:54:13 +00001175endfunc
1176
zeertzjq4f33bc22021-08-05 17:57:02 +02001177func Test_diff_with_cursorline_breakindent()
1178 CheckScreendump
1179
zeertzjq588f20d2023-12-05 15:47:09 +01001180 let lines =<< trim END
1181 hi CursorLine ctermbg=red ctermfg=white
1182 set noequalalways wrap diffopt=followwrap cursorline breakindent
1183 50vnew
1184 call setline(1, [' ', ' ', ' ', ' '])
1185 exe "norm! 20Afoo\<Esc>j20Afoo\<Esc>j20Afoo\<Esc>j20Abar\<Esc>"
1186 vnew
1187 call setline(1, [' ', ' ', ' ', ' '])
1188 exe "norm! 20Abee\<Esc>j20Afoo\<Esc>j20Afoo\<Esc>j20Abaz\<Esc>"
1189 windo diffthis
1190 2wincmd w
1191 END
1192 call writefile(lines, 'Xtest_diff_cursorline_breakindent', 'D')
zeertzjq4f33bc22021-08-05 17:57:02 +02001193 let buf = RunVimInTerminal('-S Xtest_diff_cursorline_breakindent', {})
1194
1195 call term_sendkeys(buf, "gg0")
1196 call VerifyScreenDump(buf, 'Test_diff_with_cul_bri_01', {})
1197 call term_sendkeys(buf, "j")
1198 call VerifyScreenDump(buf, 'Test_diff_with_cul_bri_02', {})
1199 call term_sendkeys(buf, "j")
1200 call VerifyScreenDump(buf, 'Test_diff_with_cul_bri_03', {})
1201 call term_sendkeys(buf, "j")
1202 call VerifyScreenDump(buf, 'Test_diff_with_cul_bri_04', {})
1203
1204 " clean up
1205 call StopVimInTerminal(buf)
zeertzjq4f33bc22021-08-05 17:57:02 +02001206endfunc
1207
zeertzjq588f20d2023-12-05 15:47:09 +01001208func Test_diff_breakindent_after_filler()
1209 CheckScreendump
1210
1211 let lines =<< trim END
zeertzjqf0a9d652024-02-12 22:53:20 +01001212 set laststatus=0 diffopt+=followwrap breakindent breakindentopt=min:0
zeertzjq588f20d2023-12-05 15:47:09 +01001213 call setline(1, ['a', ' ' .. repeat('c', 50)])
1214 vnew
1215 call setline(1, ['a', 'b', ' ' .. repeat('c', 50)])
1216 windo diffthis
1217 norm! G$
1218 END
1219 call writefile(lines, 'Xtest_diff_breakindent_after_filler', 'D')
1220 let buf = RunVimInTerminal('-S Xtest_diff_breakindent_after_filler', #{rows: 8, cols: 45})
1221 call VerifyScreenDump(buf, 'Test_diff_breakindent_after_filler', {})
1222
1223 " clean up
1224 call StopVimInTerminal(buf)
1225endfunc
1226
Bram Moolenaar248fdb32019-09-15 19:31:28 +02001227func Test_diff_with_syntax()
1228 CheckScreendump
1229
1230 let lines =<< trim END
Bram Moolenaar94722c52023-01-28 19:19:03 +00001231 void doNothing() {
Bram Moolenaar248fdb32019-09-15 19:31:28 +02001232 int x = 0;
1233 char *s = "hello";
1234 return 5;
1235 }
1236 END
Bram Moolenaar59173412022-09-20 22:01:33 +01001237 call writefile(lines, 'Xprogram1.c', 'D')
Bram Moolenaar248fdb32019-09-15 19:31:28 +02001238 let lines =<< trim END
Bram Moolenaar94722c52023-01-28 19:19:03 +00001239 void doSomething() {
Bram Moolenaar248fdb32019-09-15 19:31:28 +02001240 int x = 0;
1241 char *s = "there";
1242 return 5;
1243 }
1244 END
Bram Moolenaar59173412022-09-20 22:01:33 +01001245 call writefile(lines, 'Xprogram2.c', 'D')
Bram Moolenaar248fdb32019-09-15 19:31:28 +02001246
1247 let lines =<< trim END
Bram Moolenaar94722c52023-01-28 19:19:03 +00001248 edit Xprogram1.c
Bram Moolenaar248fdb32019-09-15 19:31:28 +02001249 diffsplit Xprogram2.c
1250 END
Bram Moolenaar59173412022-09-20 22:01:33 +01001251 call writefile(lines, 'Xtest_diff_syntax', 'D')
Bram Moolenaar248fdb32019-09-15 19:31:28 +02001252 let buf = RunVimInTerminal('-S Xtest_diff_syntax', {})
1253
1254 call VerifyScreenDump(buf, 'Test_diff_syntax_1', {})
1255
1256 " clean up
1257 call StopVimInTerminal(buf)
Bram Moolenaar248fdb32019-09-15 19:31:28 +02001258endfunc
1259
Bram Moolenaarf7acf2b2018-11-01 21:14:53 +01001260func Test_diff_of_diff()
Bram Moolenaar3c8ee622019-08-03 22:55:50 +02001261 CheckScreendump
1262 CheckFeature rightleft
Bram Moolenaarf7acf2b2018-11-01 21:14:53 +01001263
1264 call writefile([
1265 \ 'call setline(1, ["aa","bb","cc","@@ -3,2 +5,7 @@","dd","ee","ff"])',
1266 \ 'vnew',
1267 \ 'call setline(1, ["aa","bb","cc"])',
1268 \ 'windo diffthis',
Bram Moolenaar8ee4c012019-03-29 18:08:18 +01001269 \ '1wincmd w',
1270 \ 'setlocal number',
Bram Moolenaar59173412022-09-20 22:01:33 +01001271 \ ], 'Xtest_diff_diff', 'D')
Bram Moolenaarf7acf2b2018-11-01 21:14:53 +01001272 let buf = RunVimInTerminal('-S Xtest_diff_diff', {})
1273
1274 call VerifyScreenDump(buf, 'Test_diff_of_diff_01', {})
1275
Bram Moolenaare73f9112019-03-29 18:29:54 +01001276 call term_sendkeys(buf, ":set rightleft\<cr>")
1277 call VerifyScreenDump(buf, 'Test_diff_of_diff_02', {})
1278
Bram Moolenaarf7acf2b2018-11-01 21:14:53 +01001279 " clean up
1280 call StopVimInTerminal(buf)
Bram Moolenaarf7acf2b2018-11-01 21:14:53 +01001281endfunc
Bram Moolenaarc8234772019-11-10 21:00:27 +01001282
1283func CloseoffSetup()
1284 enew
1285 call setline(1, ['one', 'two', 'three'])
1286 diffthis
1287 new
1288 call setline(1, ['one', 'tow', 'three'])
1289 diffthis
1290 call assert_equal(1, &diff)
Jonathonca307ef2025-01-17 13:37:35 +01001291 bw!
Bram Moolenaarc8234772019-11-10 21:00:27 +01001292endfunc
1293
1294func Test_diff_closeoff()
1295 " "closeoff" included by default: last diff win gets 'diff' reset'
1296 call CloseoffSetup()
1297 call assert_equal(0, &diff)
1298 enew!
1299
1300 " "closeoff" excluded: last diff win keeps 'diff' set'
1301 set diffopt-=closeoff
1302 call CloseoffSetup()
1303 call assert_equal(1, &diff)
1304 diffoff!
1305 enew!
1306endfunc
Bram Moolenaarf4a1d1c2019-11-16 13:50:25 +01001307
Bram Moolenaar4223d432021-02-10 13:18:17 +01001308func Test_diff_followwrap()
1309 new
1310 set diffopt+=followwrap
1311 set wrap
1312 diffthis
1313 call assert_equal(1, &wrap)
1314 diffoff
1315 set nowrap
1316 diffthis
1317 call assert_equal(0, &wrap)
1318 diffoff
1319 set diffopt&
1320 bwipe!
1321endfunc
1322
Bram Moolenaarf4a1d1c2019-11-16 13:50:25 +01001323func Test_diff_maintains_change_mark()
Sean Dewarccc16442021-12-29 16:44:48 +00001324 func DiffMaintainsChangeMark()
1325 enew!
1326 call setline(1, ['a', 'b', 'c', 'd'])
1327 diffthis
1328 new
1329 call setline(1, ['a', 'b', 'c', 'e'])
1330 " Set '[ and '] marks
1331 2,3yank
1332 call assert_equal([2, 3], [line("'["), line("']")])
1333 " Verify they aren't affected by the implicit diff
1334 diffthis
1335 call assert_equal([2, 3], [line("'["), line("']")])
1336 " Verify they aren't affected by an explicit diff
1337 diffupdate
1338 call assert_equal([2, 3], [line("'["), line("']")])
1339 bwipe!
1340 bwipe!
1341 endfunc
1342
1343 set diffopt-=internal
1344 call DiffMaintainsChangeMark()
1345 set diffopt+=internal
1346 call DiffMaintainsChangeMark()
Bram Moolenaard9b74a22022-01-16 15:00:08 +00001347
Sean Dewarccc16442021-12-29 16:44:48 +00001348 set diffopt&
Bram Moolenaard9b74a22022-01-16 15:00:08 +00001349 delfunc DiffMaintainsChangeMark
Bram Moolenaarf4a1d1c2019-11-16 13:50:25 +01001350endfunc
Bram Moolenaar8dfcce32020-03-18 19:32:26 +01001351
1352" Test for 'patchexpr'
1353func Test_patchexpr()
1354 let g:patch_args = []
1355 func TPatch()
1356 call add(g:patch_args, readfile(v:fname_in))
1357 call add(g:patch_args, readfile(v:fname_diff))
1358 call writefile(['output file'], v:fname_out)
1359 endfunc
1360 set patchexpr=TPatch()
1361
Bram Moolenaar59173412022-09-20 22:01:33 +01001362 call writefile(['input file'], 'Xinput', 'D')
1363 call writefile(['diff file'], 'Xdiff', 'D')
Bram Moolenaar8dfcce32020-03-18 19:32:26 +01001364 %bwipe!
1365 edit Xinput
1366 diffpatch Xdiff
1367 call assert_equal('output file', getline(1))
1368 call assert_equal('Xinput.new', bufname())
1369 call assert_equal(2, winnr('$'))
1370 call assert_true(&diff)
1371
Yegappan Lakshmanan8bb65f22021-12-26 10:51:39 +00001372 " Using a script-local function
1373 func s:NewPatchExpr()
1374 endfunc
1375 set patchexpr=s:NewPatchExpr()
1376 call assert_equal(expand('<SID>') .. 'NewPatchExpr()', &patchexpr)
1377 set patchexpr=<SID>NewPatchExpr()
1378 call assert_equal(expand('<SID>') .. 'NewPatchExpr()', &patchexpr)
1379
Bram Moolenaar8dfcce32020-03-18 19:32:26 +01001380 set patchexpr&
1381 delfunc TPatch
Yegappan Lakshmanan8bb65f22021-12-26 10:51:39 +00001382 delfunc s:NewPatchExpr
Bram Moolenaar8dfcce32020-03-18 19:32:26 +01001383 %bwipe!
1384endfunc
1385
Bram Moolenaar511feec2020-06-18 19:15:27 +02001386func Test_diff_rnu()
1387 CheckScreendump
1388
1389 let content =<< trim END
1390 call setline(1, ['a', 'a', 'a', 'y', 'b', 'b', 'b', 'b', 'b'])
1391 vnew
1392 call setline(1, ['a', 'a', 'a', 'x', 'x', 'x', 'b', 'b', 'b', 'b', 'b'])
1393 windo diffthis
1394 setlocal number rnu foldcolumn=0
1395 END
Bram Moolenaar59173412022-09-20 22:01:33 +01001396 call writefile(content, 'Xtest_diff_rnu', 'D')
Bram Moolenaar511feec2020-06-18 19:15:27 +02001397 let buf = RunVimInTerminal('-S Xtest_diff_rnu', {})
1398
1399 call VerifyScreenDump(buf, 'Test_diff_rnu_01', {})
1400
1401 call term_sendkeys(buf, "j")
1402 call VerifyScreenDump(buf, 'Test_diff_rnu_02', {})
1403 call term_sendkeys(buf, "j")
1404 call VerifyScreenDump(buf, 'Test_diff_rnu_03', {})
1405
1406 " clean up
1407 call StopVimInTerminal(buf)
Bram Moolenaar511feec2020-06-18 19:15:27 +02001408endfunc
1409
Bram Moolenaarfc838d62020-06-25 22:23:48 +02001410func Test_diff_multilineconceal()
1411 new
1412 diffthis
1413
1414 new
1415 call matchadd('Conceal', 'a\nb', 9, -1, {'conceal': 'Y'})
1416 set cole=2 cocu=n
1417 call setline(1, ["a", "b"])
1418 diffthis
1419 redraw
1420endfunc
1421
Bram Moolenaar8455c5e2020-07-14 21:22:30 +02001422func Test_diff_and_scroll()
1423 " this was causing an ml_get error
1424 set ls=2
Bram Moolenaar94722c52023-01-28 19:19:03 +00001425 for i in range(winheight(0) * 2)
1426 call setline(i, i < winheight(0) - 10 ? i : i + 10)
Bram Moolenaar8455c5e2020-07-14 21:22:30 +02001427 endfor
1428 vnew
Bram Moolenaar94722c52023-01-28 19:19:03 +00001429 for i in range(winheight(0)*2 + 10)
1430 call setline(i, i < winheight(0) - 10 ? 0 : i)
Bram Moolenaar8455c5e2020-07-14 21:22:30 +02001431 endfor
1432 diffthis
1433 wincmd p
1434 diffthis
1435 execute 'normal ' . winheight(0) . "\<C-d>"
1436
1437 bwipe!
1438 bwipe!
1439 set ls&
1440endfunc
1441
Bram Moolenaarfabc3ca2020-11-05 19:07:21 +01001442func Test_diff_filler_cursorcolumn()
1443 CheckScreendump
1444
1445 let content =<< trim END
1446 call setline(1, ['aa', 'bb', 'cc'])
1447 vnew
1448 call setline(1, ['aa', 'cc'])
1449 windo diffthis
1450 wincmd p
1451 setlocal cursorcolumn foldcolumn=0
1452 norm! gg0
1453 redraw!
1454 END
Bram Moolenaar59173412022-09-20 22:01:33 +01001455 call writefile(content, 'Xtest_diff_cuc', 'D')
Bram Moolenaarfabc3ca2020-11-05 19:07:21 +01001456 let buf = RunVimInTerminal('-S Xtest_diff_cuc', {})
1457
1458 call VerifyScreenDump(buf, 'Test_diff_cuc_01', {})
1459
1460 call term_sendkeys(buf, "l")
1461 call term_sendkeys(buf, "\<C-l>")
1462 call VerifyScreenDump(buf, 'Test_diff_cuc_02', {})
1463 call term_sendkeys(buf, "0j")
1464 call term_sendkeys(buf, "\<C-l>")
1465 call VerifyScreenDump(buf, 'Test_diff_cuc_03', {})
1466 call term_sendkeys(buf, "l")
1467 call term_sendkeys(buf, "\<C-l>")
1468 call VerifyScreenDump(buf, 'Test_diff_cuc_04', {})
1469
1470 " clean up
1471 call StopVimInTerminal(buf)
Bram Moolenaarfabc3ca2020-11-05 19:07:21 +01001472endfunc
1473
Yegappan Lakshmanan30443242021-06-10 21:52:15 +02001474" Test for adding/removing lines inside diff chunks, between diff chunks
1475" and before diff chunks
1476func Test_diff_modify_chunks()
1477 enew!
1478 let w2_id = win_getid()
1479 call setline(1, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'])
1480 new
1481 let w1_id = win_getid()
1482 call setline(1, ['a', '2', '3', 'd', 'e', 'f', '7', '8', 'i'])
1483 windo diffthis
1484
1485 " remove a line between two diff chunks and create a new diff chunk
1486 call win_gotoid(w2_id)
1487 5d
1488 call win_gotoid(w1_id)
1489 call diff_hlID(5, 1)->synIDattr('name')->assert_equal('DiffAdd')
1490
1491 " add a line between two diff chunks
1492 call win_gotoid(w2_id)
1493 normal! 4Goe
1494 call win_gotoid(w1_id)
1495 call diff_hlID(4, 1)->synIDattr('name')->assert_equal('')
1496 call diff_hlID(5, 1)->synIDattr('name')->assert_equal('')
1497
1498 " remove all the lines in a diff chunk.
1499 call win_gotoid(w2_id)
1500 7,8d
1501 call win_gotoid(w1_id)
1502 let hl = range(1, 9)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')})
1503 call assert_equal(['', 'DiffText', 'DiffText', '', '', '', 'DiffAdd',
1504 \ 'DiffAdd', ''], hl)
1505
1506 " remove lines from one diff chunk to just before the next diff chunk
1507 call win_gotoid(w2_id)
1508 call setline(1, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'])
1509 2,6d
1510 call win_gotoid(w1_id)
1511 let hl = range(1, 9)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')})
1512 call assert_equal(['', 'DiffText', 'DiffText', 'DiffAdd', 'DiffAdd',
1513 \ 'DiffAdd', 'DiffAdd', 'DiffAdd', ''], hl)
1514
1515 " remove lines just before the top of a diff chunk
1516 call win_gotoid(w2_id)
1517 call setline(1, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'])
1518 5,6d
1519 call win_gotoid(w1_id)
1520 let hl = range(1, 9)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')})
1521 call assert_equal(['', 'DiffText', 'DiffText', '', 'DiffText', 'DiffText',
1522 \ 'DiffAdd', 'DiffAdd', ''], hl)
1523
1524 " remove line after the end of a diff chunk
1525 call win_gotoid(w2_id)
1526 call setline(1, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'])
1527 4d
1528 call win_gotoid(w1_id)
1529 let hl = range(1, 9)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')})
1530 call assert_equal(['', 'DiffText', 'DiffText', 'DiffAdd', '', '', 'DiffText',
1531 \ 'DiffText', ''], hl)
1532
1533 " remove lines starting from the end of one diff chunk and ending inside
1534 " another diff chunk
1535 call win_gotoid(w2_id)
1536 call setline(1, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'])
1537 4,7d
1538 call win_gotoid(w1_id)
1539 let hl = range(1, 9)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')})
1540 call assert_equal(['', 'DiffText', 'DiffText', 'DiffText', 'DiffAdd',
1541 \ 'DiffAdd', 'DiffAdd', 'DiffAdd', ''], hl)
1542
1543 " removing the only remaining diff chunk should make the files equal
1544 call win_gotoid(w2_id)
1545 call setline(1, ['a', '2', '3', 'x', 'd', 'e', 'f', 'x', '7', '8', 'i'])
1546 8d
1547 let hl = range(1, 10)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')})
1548 call assert_equal(['', '', '', 'DiffAdd', '', '', '', '', '', ''], hl)
1549 call win_gotoid(w2_id)
1550 4d
1551 call win_gotoid(w1_id)
1552 let hl = range(1, 9)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')})
1553 call assert_equal(['', '', '', '', '', '', '', '', ''], hl)
1554
1555 %bw!
1556endfunc
glacambread5c1782021-05-24 14:20:53 +02001557
Bram Moolenaar06f60952021-12-28 18:30:05 +00001558func Test_diff_binary()
1559 CheckScreendump
1560
1561 let content =<< trim END
1562 call setline(1, ['a', 'b', "c\n", 'd', 'e', 'f', 'g'])
1563 vnew
1564 call setline(1, ['A', 'b', 'c', 'd', 'E', 'f', 'g'])
1565 windo diffthis
1566 wincmd p
1567 norm! gg0
1568 redraw!
1569 END
Bram Moolenaar59173412022-09-20 22:01:33 +01001570 call writefile(content, 'Xtest_diff_bin', 'D')
Bram Moolenaar06f60952021-12-28 18:30:05 +00001571 let buf = RunVimInTerminal('-S Xtest_diff_bin', {})
1572
1573 " Test using internal diff
1574 call VerifyScreenDump(buf, 'Test_diff_bin_01', {})
1575
1576 " Test using internal diff and case folding
1577 call term_sendkeys(buf, ":set diffopt+=icase\<cr>")
1578 call term_sendkeys(buf, "\<C-l>")
1579 call VerifyScreenDump(buf, 'Test_diff_bin_02', {})
1580 " Test using external diff
1581 call term_sendkeys(buf, ":set diffopt=filler\<cr>")
1582 call term_sendkeys(buf, "\<C-l>")
1583 call VerifyScreenDump(buf, 'Test_diff_bin_03', {})
1584 " Test using external diff and case folding
1585 call term_sendkeys(buf, ":set diffopt=filler,icase\<cr>")
1586 call term_sendkeys(buf, "\<C-l>")
1587 call VerifyScreenDump(buf, 'Test_diff_bin_04', {})
1588
1589 " clean up
1590 call StopVimInTerminal(buf)
Bram Moolenaar06f60952021-12-28 18:30:05 +00001591 set diffopt&vim
1592endfunc
1593
Yegappan Lakshmananb0ad2d92022-01-27 13:16:59 +00001594" Test for using the 'zi' command to invert 'foldenable' in diff windows (test
1595" for the issue fixed by patch 6.2.317)
1596func Test_diff_foldinvert()
1597 %bw!
Bram Moolenaar61abe7d2022-08-30 21:46:08 +01001598 edit Xdoffile1
1599 new Xdoffile2
1600 new Xdoffile3
Yegappan Lakshmananb0ad2d92022-01-27 13:16:59 +00001601 windo diffthis
1602 " open a non-diff window
1603 botright new
1604 1wincmd w
1605 call assert_true(getwinvar(1, '&foldenable'))
1606 call assert_true(getwinvar(2, '&foldenable'))
1607 call assert_true(getwinvar(3, '&foldenable'))
1608 normal zi
1609 call assert_false(getwinvar(1, '&foldenable'))
1610 call assert_false(getwinvar(2, '&foldenable'))
1611 call assert_false(getwinvar(3, '&foldenable'))
1612 normal zi
1613 call assert_true(getwinvar(1, '&foldenable'))
1614 call assert_true(getwinvar(2, '&foldenable'))
1615 call assert_true(getwinvar(3, '&foldenable'))
1616
1617 " If the current window has 'noscrollbind', then 'zi' should not change
1618 " 'foldenable' in other windows.
1619 1wincmd w
1620 set noscrollbind
1621 normal zi
1622 call assert_false(getwinvar(1, '&foldenable'))
1623 call assert_true(getwinvar(2, '&foldenable'))
1624 call assert_true(getwinvar(3, '&foldenable'))
1625
1626 " 'zi' should not change the 'foldenable' for windows with 'noscrollbind'
1627 1wincmd w
1628 set scrollbind
1629 normal zi
1630 call setwinvar(2, '&scrollbind', v:false)
1631 normal zi
1632 call assert_false(getwinvar(1, '&foldenable'))
1633 call assert_true(getwinvar(2, '&foldenable'))
1634 call assert_false(getwinvar(3, '&foldenable'))
1635
1636 %bw!
1637 set scrollbind&
1638endfunc
1639
Bram Moolenaara315ce12022-06-24 12:38:57 +01001640" This was scrolling for 'cursorbind' but 'scrollbind' is more important
1641func Test_diff_scroll()
1642 CheckScreendump
1643
1644 let left =<< trim END
1645 line 1
1646 line 2
1647 line 3
1648 line 4
1649
1650 // Common block
1651 // one
1652 // containing
1653 // four lines
1654
1655 // Common block
1656 // two
1657 // containing
1658 // four lines
1659 END
Bram Moolenaar59173412022-09-20 22:01:33 +01001660 call writefile(left, 'Xleft', 'D')
Bram Moolenaara315ce12022-06-24 12:38:57 +01001661 let right =<< trim END
1662 line 1
1663 line 2
1664 line 3
1665 line 4
1666
1667 Lorem
1668 ipsum
1669 dolor
1670 sit
1671 amet,
1672 consectetur
1673 adipiscing
1674 elit.
1675 Etiam
1676 luctus
1677 lectus
1678 sodales,
1679 dictum
1680
1681 // Common block
1682 // one
1683 // containing
1684 // four lines
1685
1686 Vestibulum
1687 tincidunt
1688 aliquet
1689 nulla.
1690
1691 // Common block
1692 // two
1693 // containing
1694 // four lines
1695 END
Bram Moolenaar59173412022-09-20 22:01:33 +01001696 call writefile(right, 'Xright', 'D')
Bram Moolenaara315ce12022-06-24 12:38:57 +01001697 let buf = RunVimInTerminal('-d Xleft Xright', {'rows': 12})
1698 call term_sendkeys(buf, "\<C-W>\<C-W>jjjj")
1699 call VerifyScreenDump(buf, 'Test_diff_scroll_1', {})
1700 call term_sendkeys(buf, "j")
1701 call VerifyScreenDump(buf, 'Test_diff_scroll_2', {})
1702
1703 call StopVimInTerminal(buf)
Bram Moolenaara315ce12022-06-24 12:38:57 +01001704endfunc
1705
Bram Moolenaar38d867f2023-04-01 19:54:40 +01001706" This was scrolling too many lines.
1707func Test_diff_scroll_wrap_on()
1708 20new
1709 40vsplit
1710 call setline(1, map(range(1, 9), 'repeat(v:val, 200)'))
1711 setlocal number diff so=0
1712 redraw
1713 normal! jj
1714 call assert_equal(1, winsaveview().topline)
1715 normal! j
1716 call assert_equal(2, winsaveview().topline)
zeertzjq05834912023-10-04 20:12:37 +02001717
1718 bwipe!
1719 bwipe!
1720endfunc
1721
1722func Test_diff_scroll_many_filler()
1723 20new
1724 vnew
Luuk van Baalb9f5b952024-03-26 18:46:45 +01001725 call setline(1, range(1, 40))
zeertzjq05834912023-10-04 20:12:37 +02001726 diffthis
1727 setlocal scrolloff=0
1728 wincmd p
Luuk van Baalb9f5b952024-03-26 18:46:45 +01001729 call setline(1, range(1, 20)->reverse() + ['###']->repeat(41) + range(21, 40)->reverse())
zeertzjq05834912023-10-04 20:12:37 +02001730 diffthis
1731 setlocal scrolloff=0
1732 wincmd p
1733 redraw
1734
1735 " Note: need a redraw after each scroll, otherwise the test always passes.
Luuk van Baalb9f5b952024-03-26 18:46:45 +01001736 for _ in range(2)
1737 normal! G
1738 redraw
1739 call assert_equal(40, winsaveview().topline)
1740 call assert_equal(19, winsaveview().topfill)
1741 exe "normal! \<C-B>"
1742 redraw
1743 call assert_equal(22, winsaveview().topline)
1744 call assert_equal(0, winsaveview().topfill)
1745 exe "normal! \<C-B>"
1746 redraw
1747 call assert_equal(4, winsaveview().topline)
1748 call assert_equal(0, winsaveview().topfill)
1749 exe "normal! \<C-B>"
1750 redraw
1751 call assert_equal(1, winsaveview().topline)
1752 call assert_equal(0, winsaveview().topfill)
1753 set smoothscroll
1754 endfor
zeertzjq05834912023-10-04 20:12:37 +02001755
Luuk van Baalb9f5b952024-03-26 18:46:45 +01001756 set smoothscroll&
Luuk van Baalcb204e62024-04-02 20:49:45 +02001757 %bwipe!
Bram Moolenaar38d867f2023-04-01 19:54:40 +01001758endfunc
1759
Bram Moolenaarcd38bb42022-06-26 14:04:07 +01001760" This was trying to update diffs for a buffer being closed
1761func Test_diff_only()
1762 silent! lfile
1763 set diff
1764 lopen
1765 norm o
1766 silent! norm o
1767
1768 set nodiff
1769 %bwipe!
1770endfunc
1771
Bram Moolenaarc101abf2022-06-26 16:53:34 +01001772" This was causing invalid diff block values
1773" FIXME: somehow this causes a valgrind error when run directly but not when
1774" run as a test.
1775func Test_diff_manipulations()
1776 set diff
1777 split 0
1778 sil! norm R doobdeuR doobdeuR doobdeu
1779
1780 set nodiff
1781 %bwipe!
1782endfunc
1783
Bram Moolenaar4e677b92022-07-28 18:44:27 +01001784" This was causing the line number in the diff block to go below one.
1785" FIXME: somehow this causes a valgrind error when run directly but not when
1786" run as a test.
1787func Test_diff_put_and_undo()
1788 set diff
1789 next 0
1790 split 00
1791 sil! norm o0gguudpo0ggJuudp
1792
1793 bwipe!
1794 bwipe!
1795 set nodiff
1796endfunc
1797
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001798" Test for the diff() function
1799def Test_diff_func()
1800 # string is added/removed/modified at the beginning
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001801 assert_equal("@@ -0,0 +1 @@\n+abc\n",
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001802 diff(['def'], ['abc', 'def'], {output: 'unified'}))
1803 assert_equal([{from_idx: 0, from_count: 0, to_idx: 0, to_count: 1}],
1804 diff(['def'], ['abc', 'def'], {output: 'indices'}))
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001805 assert_equal("@@ -1 +0,0 @@\n-abc\n",
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001806 diff(['abc', 'def'], ['def'], {output: 'unified'}))
1807 assert_equal([{from_idx: 0, from_count: 1, to_idx: 0, to_count: 0}],
1808 diff(['abc', 'def'], ['def'], {output: 'indices'}))
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001809 assert_equal("@@ -1 +1 @@\n-abc\n+abx\n",
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001810 diff(['abc', 'def'], ['abx', 'def'], {output: 'unified'}))
1811 assert_equal([{from_idx: 0, from_count: 1, to_idx: 0, to_count: 1}],
1812 diff(['abc', 'def'], ['abx', 'def'], {output: 'indices'}))
1813
1814 # string is added/removed/modified at the end
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001815 assert_equal("@@ -1,0 +2 @@\n+def\n",
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001816 diff(['abc'], ['abc', 'def'], {output: 'unified'}))
1817 assert_equal([{from_idx: 1, from_count: 0, to_idx: 1, to_count: 1}],
1818 diff(['abc'], ['abc', 'def'], {output: 'indices'}))
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001819 assert_equal("@@ -2 +1,0 @@\n-def\n",
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001820 diff(['abc', 'def'], ['abc'], {output: 'unified'}))
1821 assert_equal([{from_idx: 1, from_count: 1, to_idx: 1, to_count: 0}],
1822 diff(['abc', 'def'], ['abc'], {output: 'indices'}))
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001823 assert_equal("@@ -2 +2 @@\n-def\n+xef\n",
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001824 diff(['abc', 'def'], ['abc', 'xef'], {output: 'unified'}))
1825 assert_equal([{from_idx: 1, from_count: 1, to_idx: 1, to_count: 1}],
1826 diff(['abc', 'def'], ['abc', 'xef'], {output: 'indices'}))
1827
1828 # string is added/removed/modified in the middle
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001829 assert_equal("@@ -2,0 +3 @@\n+xxx\n",
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001830 diff(['111', '222', '333'], ['111', '222', 'xxx', '333'], {output: 'unified'}))
1831 assert_equal([{from_idx: 2, from_count: 0, to_idx: 2, to_count: 1}],
1832 diff(['111', '222', '333'], ['111', '222', 'xxx', '333'], {output: 'indices'}))
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001833 assert_equal("@@ -3 +2,0 @@\n-333\n",
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001834 diff(['111', '222', '333', '444'], ['111', '222', '444'], {output: 'unified'}))
1835 assert_equal([{from_idx: 2, from_count: 1, to_idx: 2, to_count: 0}],
1836 diff(['111', '222', '333', '444'], ['111', '222', '444'], {output: 'indices'}))
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001837 assert_equal("@@ -3 +3 @@\n-333\n+xxx\n",
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001838 diff(['111', '222', '333', '444'], ['111', '222', 'xxx', '444'], {output: 'unified'}))
1839 assert_equal([{from_idx: 2, from_count: 1, to_idx: 2, to_count: 1}],
1840 diff(['111', '222', '333', '444'], ['111', '222', 'xxx', '444'], {output: 'indices'}))
1841
1842 # new strings are added to an empty List
1843 assert_equal("@@ -0,0 +1,2 @@\n+abc\n+def\n",
1844 diff([], ['abc', 'def'], {output: 'unified'}))
1845 assert_equal([{from_idx: 0, from_count: 0, to_idx: 0, to_count: 2}],
1846 diff([], ['abc', 'def'], {output: 'indices'}))
1847
1848 # all the strings are removed from a List
1849 assert_equal("@@ -1,2 +0,0 @@\n-abc\n-def\n",
1850 diff(['abc', 'def'], [], {output: 'unified'}))
1851 assert_equal([{from_idx: 0, from_count: 2, to_idx: 0, to_count: 0}],
1852 diff(['abc', 'def'], [], {output: 'indices'}))
1853
1854 # First character is added/removed/different
1855 assert_equal("@@ -1 +1 @@\n-abc\n+bc\n",
1856 diff(['abc'], ['bc'], {output: 'unified'}))
1857 assert_equal([{from_idx: 0, from_count: 1, to_idx: 0, to_count: 1}],
1858 diff(['abc'], ['bc'], {output: 'indices'}))
1859 assert_equal("@@ -1 +1 @@\n-bc\n+abc\n",
1860 diff(['bc'], ['abc'], {output: 'unified'}))
1861 assert_equal([{from_idx: 0, from_count: 1, to_idx: 0, to_count: 1}],
1862 diff(['bc'], ['abc'], {output: 'indices'}))
1863 assert_equal("@@ -1 +1 @@\n-abc\n+xbc\n",
1864 diff(['abc'], ['xbc'], {output: 'unified'}))
1865 assert_equal([{from_idx: 0, from_count: 1, to_idx: 0, to_count: 1}],
1866 diff(['abc'], ['xbc'], {output: 'indices'}))
1867
1868 # Last character is added/removed/different
1869 assert_equal("@@ -1 +1 @@\n-abc\n+abcd\n",
1870 diff(['abc'], ['abcd'], {output: 'unified'}))
1871 assert_equal([{from_idx: 0, from_count: 1, to_idx: 0, to_count: 1}],
1872 diff(['abc'], ['abcd'], {output: 'indices'}))
1873 assert_equal("@@ -1 +1 @@\n-abcd\n+abc\n",
1874 diff(['abcd'], ['abc'], {output: 'unified'}))
1875 assert_equal([{from_idx: 0, from_count: 1, to_idx: 0, to_count: 1}],
1876 diff(['abcd'], ['abc'], {output: 'indices'}))
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001877 var diff_unified: string = diff(['abc'], ['abx'], {output: 'unified'})
1878 assert_equal("@@ -1 +1 @@\n-abc\n+abx\n", diff_unified)
1879 var diff_indices: list<dict<number>> =
1880 diff(['abc'], ['abx'], {output: 'indices'})
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001881 assert_equal([{from_idx: 0, from_count: 1, to_idx: 0, to_count: 1}],
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001882 diff_indices)
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001883
1884 # partial string modification at the start and at the end.
1885 var fromlist =<< trim END
1886 one two
1887 three four
1888 five six
1889 END
1890 var tolist =<< trim END
1891 one
1892 six
1893 END
1894 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'}))
1895 assert_equal([{from_idx: 0, from_count: 3, to_idx: 0, to_count: 2}],
1896 diff(fromlist, tolist, {output: 'indices'}))
1897
1898 # non-contiguous modifications
1899 fromlist =<< trim END
1900 one two
1901 three four
1902 five abc six
1903 END
1904 tolist =<< trim END
1905 one abc two
1906 three four
1907 five six
1908 END
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001909 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 +01001910 diff(fromlist, tolist, {output: 'unified'}))
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001911 assert_equal([{'from_count': 1, 'to_idx': 0, 'to_count': 1, 'from_idx': 0},
1912 {'from_count': 1, 'to_idx': 2, 'to_count': 1, 'from_idx': 2}],
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001913 diff(fromlist, tolist, {output: 'indices'}))
1914
1915 # add/remove blank lines
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001916 assert_equal("@@ -2,2 +1,0 @@\n-\n-\n",
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001917 diff(['one', '', '', 'two'], ['one', 'two'], {output: 'unified'}))
1918 assert_equal([{from_idx: 1, from_count: 2, to_idx: 1, to_count: 0}],
1919 diff(['one', '', '', 'two'], ['one', 'two'], {output: 'indices'}))
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001920 assert_equal("@@ -1,0 +2,2 @@\n+\n+\n",
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001921 diff(['one', 'two'], ['one', '', '', 'two'], {output: 'unified'}))
1922 assert_equal([{'from_idx': 1, 'from_count': 0, 'to_idx': 1, 'to_count': 2}],
1923 diff(['one', 'two'], ['one', '', '', 'two'], {output: 'indices'}))
1924
1925 # diff ignoring case
1926 assert_equal('', diff(['abc', 'def'], ['ABC', 'DEF'], {icase: true, output: 'unified'}))
1927 assert_equal([], diff(['abc', 'def'], ['ABC', 'DEF'], {icase: true, output: 'indices'}))
1928
1929 # diff ignoring all whitespace changes except leading whitespace changes
1930 assert_equal('', diff(['abc def'], ['abc def '], {iwhite: true}))
1931 assert_equal("@@ -1 +1 @@\n- abc\n+ xxx\n", diff([' abc'], [' xxx'], {iwhite: v:true}))
1932 assert_equal("@@ -1 +1 @@\n- abc\n+ xxx\n", diff([' abc'], [' xxx'], {iwhite: v:false}))
1933 assert_equal("@@ -1 +1 @@\n-abc \n+xxx \n", diff(['abc '], ['xxx '], {iwhite: v:true}))
1934 assert_equal("@@ -1 +1 @@\n-abc \n+xxx \n", diff(['abc '], ['xxx '], {iwhite: v:false}))
1935
1936 # diff ignoring all whitespace changes
1937 assert_equal('', diff(['abc def'], [' abc def '], {iwhiteall: true}))
1938 assert_equal("@@ -1 +1 @@\n- abc \n+ xxx \n", diff([' abc '], [' xxx '], {iwhiteall: v:true}))
1939 assert_equal("@@ -1 +1 @@\n- abc \n+ xxx \n", diff([' abc '], [' xxx '], {iwhiteall: v:false}))
1940
1941 # diff ignoring trailing whitespace changes
1942 assert_equal('', diff(['abc'], ['abc '], {iwhiteeol: true}))
1943
1944 # diff ignoring blank lines
1945 assert_equal('', diff(['one', '', '', 'two'], ['one', 'two'], {iblank: true}))
1946 assert_equal('', diff(['one', 'two'], ['one', '', '', 'two'], {iblank: true}))
1947
1948 # same string
1949 assert_equal('', diff(['abc', 'def', 'ghi'], ['abc', 'def', 'ghi']))
1950 assert_equal('', diff([''], ['']))
1951 assert_equal('', diff([], []))
1952
1953 # different xdiff algorithms
1954 for algo in ['myers', 'minimal', 'patience', 'histogram']
1955 assert_equal("@@ -1 +1 @@\n- abc \n+ xxx \n",
1956 diff([' abc '], [' xxx '], {algorithm: algo, output: 'unified'}))
1957 assert_equal([{from_idx: 0, from_count: 1, to_idx: 0, to_count: 1}],
1958 diff([' abc '], [' xxx '], {algorithm: algo, output: 'indices'}))
1959 endfor
1960 assert_equal("@@ -1 +1 @@\n- abc \n+ xxx \n",
1961 diff([' abc '], [' xxx '], {indent-heuristic: true, output: 'unified'}))
1962 assert_equal([{from_idx: 0, from_count: 1, to_idx: 0, to_count: 1}],
1963 diff([' abc '], [' xxx '], {indent-heuristic: true, output: 'indices'}))
1964
1965 # identical strings
1966 assert_equal('', diff(['111', '222'], ['111', '222'], {output: 'unified'}))
1967 assert_equal([], diff(['111', '222'], ['111', '222'], {output: 'indices'}))
1968 assert_equal('', diff([], [], {output: 'unified'}))
1969 assert_equal([], diff([], [], {output: 'indices'}))
1970
Yegappan Lakshmananbe156a32024-02-11 17:08:29 +01001971 # If 'diffexpr' is set, it should not be used for diff()
1972 def MyDiffExpr()
1973 enddef
1974 var save_diffexpr = &diffexpr
1975 :set diffexpr=MyDiffExpr()
1976 assert_equal("@@ -1 +1 @@\n-abc\n+\n",
1977 diff(['abc'], [''], {output: 'unified'}))
1978 assert_equal([{'from_idx': 0, 'from_count': 1, 'to_idx': 0, 'to_count': 1}],
1979 diff(['abc'], [''], {output: 'indices'}))
1980 assert_equal('MyDiffExpr()', &diffexpr)
1981 &diffexpr = save_diffexpr
1982
1983 # try different values for unified diff 'context'
1984 assert_equal("@@ -0,0 +1 @@\n+x\n",
1985 diff(['a', 'b', 'c'], ['x', 'a', 'b', 'c']))
1986 assert_equal("@@ -0,0 +1 @@\n+x\n",
1987 diff(['a', 'b', 'c'], ['x', 'a', 'b', 'c'], {context: 0}))
1988 assert_equal("@@ -1 +1,2 @@\n+x\n a\n",
1989 diff(['a', 'b', 'c'], ['x', 'a', 'b', 'c'], {context: 1}))
1990 assert_equal("@@ -1,2 +1,3 @@\n+x\n a\n b\n",
1991 diff(['a', 'b', 'c'], ['x', 'a', 'b', 'c'], {context: 2}))
1992 assert_equal("@@ -1,3 +1,4 @@\n+x\n a\n b\n c\n",
1993 diff(['a', 'b', 'c'], ['x', 'a', 'b', 'c'], {context: 3}))
1994 assert_equal("@@ -1,3 +1,4 @@\n+x\n a\n b\n c\n",
1995 diff(['a', 'b', 'c'], ['x', 'a', 'b', 'c'], {context: 4}))
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001996 assert_equal("@@ -0,0 +1 @@\n+x\n",
Yegappan Lakshmananbe156a32024-02-11 17:08:29 +01001997 diff(['a', 'b', 'c'], ['x', 'a', 'b', 'c'], {context: -1}))
1998
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001999 # Error cases
2000 assert_fails('call diff({}, ["a"])', 'E1211:')
2001 assert_fails('call diff(["a"], {})', 'E1211:')
2002 assert_fails('call diff(["a"], ["a"], [])', 'E1206:')
2003 assert_fails('call diff(["a"], ["a"], {output: "xyz"})', 'E106: Unsupported diff output format: xyz')
Yegappan Lakshmananbe156a32024-02-11 17:08:29 +01002004 assert_fails('call diff(["a"], ["a"], {context: []})', 'E745: Using a List as a Number')
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01002005enddef
Bram Moolenaara315ce12022-06-24 12:38:57 +01002006
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01002007" Test for using the diff() function with 'diffexpr'
2008func Test_diffexpr_with_diff_func()
2009 CheckScreendump
2010
2011 let lines =<< trim END
2012 def DiffFuncExpr()
2013 var in: list<string> = readfile(v:fname_in)
2014 var new: list<string> = readfile(v:fname_new)
2015 var out: string = diff(in, new)
2016 writefile(split(out, "\n"), v:fname_out)
2017 enddef
2018 set diffexpr=DiffFuncExpr()
2019
2020 edit Xdifffunc1.txt
2021 diffthis
2022 vert split Xdifffunc2.txt
2023 diffthis
2024 END
2025 call writefile(lines, 'XsetupDiffFunc.vim', 'D')
2026
2027 call writefile(['zero', 'one', 'two', 'three'], 'Xdifffunc1.txt', 'D')
2028 call writefile(['one', 'twox', 'three', 'four'], 'Xdifffunc2.txt', 'D')
2029
2030 let buf = RunVimInTerminal('-S XsetupDiffFunc.vim', {'rows': 12})
2031 call VerifyScreenDump(buf, 'Test_difffunc_diffexpr_1', {})
2032 call StopVimInTerminal(buf)
2033endfunc
2034
zeertzjq9e7f1fc2024-03-16 09:40:22 +01002035func Test_diff_toggle_wrap_skipcol_leftcol()
2036 61vnew
2037 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.')
2038 30vnew
2039 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.')
2040 let win1 = win_getid()
2041 setlocal smoothscroll
2042 exe "normal! $\<C-E>"
2043 wincmd l
2044 let win2 = win_getid()
2045 setlocal smoothscroll
2046 exe "normal! $\<C-E>"
2047 call assert_equal([
2048 \ '<<<sadipscing elitr, sed diam |<<<tetur sadipscing elitr, sed|',
2049 \ 'nonumy eirmod tempor invidunt | diam nonumy eirmod tempor inv|',
2050 \ 'ut labore et dolore magna aliq|idunt ut labore et dolore magn|',
2051 \ 'uyam erat, sed diam voluptua. |a aliquyam erat, sed diam volu|',
2052 \ '~ |ptua. |',
2053 \ ], ScreenLines([1, 5], 62))
2054 call assert_equal({'col': 29, 'row': 4, 'endcol': 29, 'curscol': 29},
2055 \ screenpos(win1, line('.', win1), col('.', win1)))
2056 call assert_equal({'col': 36, 'row': 5, 'endcol': 36, 'curscol': 36},
2057 \ screenpos(win2, line('.', win2), col('.', win2)))
2058
2059 wincmd h
2060 diffthis
2061 wincmd l
2062 diffthis
2063 normal! 0
2064 call assert_equal([
2065 \ ' ipsum dolor sit amet, conset| Lorem ipsum dolor sit amet, |',
2066 \ '~ |~ |',
2067 \ ], ScreenLines([1, 2], 62))
2068 call assert_equal({'col': 3, 'row': 1, 'endcol': 3, 'curscol': 3},
2069 \ screenpos(win1, line('.', win1), col('.', win1)))
2070 call assert_equal({'col': 34, 'row': 1, 'endcol': 34, 'curscol': 34},
2071 \ screenpos(win2, line('.', win2), col('.', win2)))
2072
2073 normal! $
2074 call assert_equal([
2075 \ ' voluptua. | diam voluptua. |',
2076 \ '~ |~ |',
2077 \ ], ScreenLines([1, 2], 62))
2078 call assert_equal({'col': 11, 'row': 1, 'endcol': 11, 'curscol': 11},
2079 \ screenpos(win1, line('.', win1), col('.', win1)))
2080 call assert_equal({'col': 48, 'row': 1, 'endcol': 48, 'curscol': 48},
2081 \ screenpos(win2, line('.', win2), col('.', win2)))
2082
2083 diffoff!
2084 call assert_equal([
2085 \ 'ipsum dolor sit amet, consetet|Lorem ipsum dolor sit amet, co|',
2086 \ 'ur sadipscing elitr, sed diam |nsetetur sadipscing elitr, sed|',
2087 \ 'nonumy eirmod tempor invidunt | diam nonumy eirmod tempor inv|',
2088 \ 'ut labore et dolore magna aliq|idunt ut labore et dolore magn|',
2089 \ 'uyam erat, sed diam voluptua. |a aliquyam erat, sed diam volu|',
2090 \ '~ |ptua. |',
2091 \ ], ScreenLines([1, 6], 62))
2092 call assert_equal({'col': 29, 'row': 5, 'endcol': 29, 'curscol': 29},
2093 \ screenpos(win1, line('.', win1), col('.', win1)))
2094 call assert_equal({'col': 36, 'row': 6, 'endcol': 36, 'curscol': 36},
2095 \ screenpos(win2, line('.', win2), col('.', win2)))
2096
2097 bwipe!
2098 bwipe!
2099endfunc
2100
Luuk van Baal9148ba82024-04-08 22:27:41 +02002101" Ctrl-D reveals filler lines below the last line in the buffer.
2102func Test_diff_eob_halfpage()
Luuk van Baal08b0f632024-04-09 22:43:49 +02002103 new
Luuk van Baal9148ba82024-04-08 22:27:41 +02002104 call setline(1, ['']->repeat(10) + ['a'])
2105 diffthis
Luuk van Baal08b0f632024-04-09 22:43:49 +02002106 new
Luuk van Baal9148ba82024-04-08 22:27:41 +02002107 call setline(1, ['']->repeat(3) + ['a', 'b'])
2108 diffthis
Luuk van Baal08b0f632024-04-09 22:43:49 +02002109 resize 5
Luuk van Baal9148ba82024-04-08 22:27:41 +02002110 wincmd j
Luuk van Baal08b0f632024-04-09 22:43:49 +02002111 resize 5
2112 norm G
2113 call assert_equal(7, line('w0'))
2114 exe "norm! \<C-D>"
2115 call assert_equal(8, line('w0'))
Luuk van Baal9148ba82024-04-08 22:27:41 +02002116
2117 %bwipe!
2118endfunc
2119
Yukihiro Nakadaira06fe70c2024-09-26 16:19:42 +02002120func Test_diff_overlapped_diff_blocks_will_be_merged()
2121 CheckScreendump
2122
2123 let lines =<< trim END
2124 func DiffExprStub()
2125 let txt_in = readfile(v:fname_in)
2126 let txt_new = readfile(v:fname_new)
2127 if txt_in == ["line1"] && txt_new == ["line2"]
2128 call writefile(["1c1"], v:fname_out)
2129 elseif txt_in == readfile("Xdiin1") && txt_new == readfile("Xdinew1")
2130 call writefile(readfile("Xdiout1"), v:fname_out)
2131 elseif txt_in == readfile("Xdiin2") && txt_new == readfile("Xdinew2")
2132 call writefile(readfile("Xdiout2"), v:fname_out)
2133 endif
2134 endfunc
2135 END
2136 call writefile(lines, 'XdiffSetup', 'D')
2137
2138 call WriteDiffFiles(0, [], [])
2139 let buf = RunVimInTerminal('-d -S XdiffSetup Xdifile1 Xdifile2', {})
2140 call term_sendkeys(buf, ":set autoread\<CR>\<c-w>w:set autoread\<CR>\<c-w>w")
2141
2142 call WriteDiffFiles(buf, ["a", "b"], ["x", "x"])
2143 call writefile(["a", "b"], "Xdiin1")
2144 call writefile(["x", "x"], "Xdinew1")
2145 call writefile(["1c1", "2c2"], "Xdiout1")
2146 call term_sendkeys(buf, ":set diffexpr=DiffExprStub()\<CR>:")
2147 call VerifyBoth(buf, "Test_diff_overlapped_2.01", "")
2148 call term_sendkeys(buf, ":set diffexpr&\<CR>:")
2149
2150 call WriteDiffFiles(buf, ["a", "b", "c"], ["x", "c"])
2151 call writefile(["a", "b", "c"], "Xdiin1")
2152 call writefile(["x", "c"], "Xdinew1")
2153 call writefile(["1c1", "2d1"], "Xdiout1")
2154 call term_sendkeys(buf, ":set diffexpr=DiffExprStub()\<CR>:")
2155 call VerifyBoth(buf, "Test_diff_overlapped_2.02", "")
2156 call term_sendkeys(buf, ":set diffexpr&\<CR>:")
2157
2158 call WriteDiffFiles(buf, ["a", "c"], ["x", "x", "c"])
2159 call writefile(["a", "c"], "Xdiin1")
2160 call writefile(["x", "x", "c"], "Xdinew1")
2161 call writefile(["1c1", "1a2"], "Xdiout1")
2162 call term_sendkeys(buf, ":set diffexpr=DiffExprStub()\<CR>:")
2163 call VerifyBoth(buf, "Test_diff_overlapped_2.03", "")
2164 call term_sendkeys(buf, ":set diffexpr&\<CR>:")
2165
2166 call StopVimInTerminal(buf)
2167 wincmd c
2168
2169 call WriteDiffFiles3(0, [], [], [])
2170 let buf = RunVimInTerminal('-d -S XdiffSetup Xdifile1 Xdifile2 Xdifile3', {})
2171 call term_sendkeys(buf, ":set autoread\<CR>\<c-w>w:set autoread\<CR>\<c-w>w:set autoread\<CR>\<c-w>w")
2172
2173 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["y", "b", "c"])
2174 call VerifyBoth(buf, "Test_diff_overlapped_3.01", "")
2175
2176 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["a", "y", "c"])
2177 call VerifyBoth(buf, "Test_diff_overlapped_3.02", "")
2178
2179 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["a", "b", "y"])
2180 call VerifyBoth(buf, "Test_diff_overlapped_3.03", "")
2181
2182 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["y", "y", "c"])
2183 call VerifyBoth(buf, "Test_diff_overlapped_3.04", "")
2184
2185 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["a", "y", "y"])
2186 call VerifyBoth(buf, "Test_diff_overlapped_3.05", "")
2187
2188 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["y", "y", "y"])
2189 call VerifyBoth(buf, "Test_diff_overlapped_3.06", "")
2190
2191 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "x"], ["y", "y", "c"])
2192 call VerifyBoth(buf, "Test_diff_overlapped_3.07", "")
2193
2194 call WriteDiffFiles3(buf, ["a", "b", "c"], ["x", "x", "c"], ["a", "y", "y"])
2195 call VerifyBoth(buf, "Test_diff_overlapped_3.08", "")
2196
2197 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["y", "y", "y", "d", "e"])
2198 call VerifyBoth(buf, "Test_diff_overlapped_3.09", "")
2199
2200 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["y", "y", "y", "y", "e"])
2201 call VerifyBoth(buf, "Test_diff_overlapped_3.10", "")
2202
2203 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["y", "y", "y", "y", "y"])
2204 call VerifyBoth(buf, "Test_diff_overlapped_3.11", "")
2205
2206 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "y", "y", "d", "e"])
2207 call VerifyBoth(buf, "Test_diff_overlapped_3.12", "")
2208
2209 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "y", "y", "y", "e"])
2210 call VerifyBoth(buf, "Test_diff_overlapped_3.13", "")
2211
2212 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "y", "y", "y", "y"])
2213 call VerifyBoth(buf, "Test_diff_overlapped_3.14", "")
2214
2215 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "b", "y", "d", "e"])
2216 call VerifyBoth(buf, "Test_diff_overlapped_3.15", "")
2217
2218 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "b", "y", "y", "e"])
2219 call VerifyBoth(buf, "Test_diff_overlapped_3.16", "")
2220
2221 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "b", "y", "y", "y"])
2222 call VerifyBoth(buf, "Test_diff_overlapped_3.17", "")
2223
2224 call WriteDiffFiles3(buf, ["a", "b"], ["x", "b"], ["y", "y"])
2225 call writefile(["a", "b"], "Xdiin1")
2226 call writefile(["x", "b"], "Xdinew1")
2227 call writefile(["1c1"], "Xdiout1")
2228 call writefile(["a", "b"], "Xdiin2")
2229 call writefile(["y", "y"], "Xdinew2")
2230 call writefile(["1c1", "2c2"], "Xdiout2")
2231 call term_sendkeys(buf, ":set diffexpr=DiffExprStub()\<CR>:")
2232 call VerifyInternal(buf, "Test_diff_overlapped_3.18", "")
2233 call term_sendkeys(buf, ":set diffexpr&\<CR>:")
2234
2235 call WriteDiffFiles3(buf, ["a", "b", "c", "d"], ["x", "b", "x", "d"], ["y", "y", "c", "d"])
2236 call writefile(["a", "b", "c", "d"], "Xdiin1")
2237 call writefile(["x", "b", "x", "d"], "Xdinew1")
2238 call writefile(["1c1", "3c3"], "Xdiout1")
2239 call writefile(["a", "b", "c", "d"], "Xdiin2")
2240 call writefile(["y", "y", "c", "d"], "Xdinew2")
2241 call writefile(["1c1", "2c2"], "Xdiout2")
2242 call term_sendkeys(buf, ":set diffexpr=DiffExprStub()\<CR>:")
2243 call VerifyInternal(buf, "Test_diff_overlapped_3.19", "")
2244 call term_sendkeys(buf, ":set diffexpr&\<CR>:")
2245
2246 call WriteDiffFiles3(buf, ["a", "b", "c", "d"], ["x", "b", "x", "d"], ["y", "y", "y", "d"])
2247 call writefile(["a", "b", "c", "d"], "Xdiin1")
2248 call writefile(["x", "b", "x", "d"], "Xdinew1")
2249 call writefile(["1c1", "3c3"], "Xdiout1")
2250 call writefile(["a", "b", "c", "d"], "Xdiin2")
2251 call writefile(["y", "y", "y", "d"], "Xdinew2")
2252 call writefile(["1c1", "2,3c2,3"], "Xdiout2")
2253 call term_sendkeys(buf, ":set diffexpr=DiffExprStub()\<CR>:")
2254 call VerifyInternal(buf, "Test_diff_overlapped_3.20", "")
2255 call term_sendkeys(buf, ":set diffexpr&\<CR>:")
2256
2257 call WriteDiffFiles3(buf, ["a", "b", "c", "d"], ["x", "b", "x", "d"], ["y", "y", "y", "y"])
2258 call writefile(["a", "b", "c", "d"], "Xdiin1")
2259 call writefile(["x", "b", "x", "d"], "Xdinew1")
2260 call writefile(["1c1", "3c3"], "Xdiout1")
2261 call writefile(["a", "b", "c", "d"], "Xdiin2")
2262 call writefile(["y", "y", "y", "y"], "Xdinew2")
2263 call writefile(["1c1", "2,4c2,4"], "Xdiout2")
2264 call term_sendkeys(buf, ":set diffexpr=DiffExprStub()\<CR>:")
2265 call VerifyInternal(buf, "Test_diff_overlapped_3.21", "")
2266 call term_sendkeys(buf, ":set diffexpr&\<CR>:")
2267
2268 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["b", "c"])
2269 call VerifyBoth(buf, "Test_diff_overlapped_3.22", "")
2270
2271 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["c"])
2272 call VerifyBoth(buf, "Test_diff_overlapped_3.23", "")
2273
2274 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], [])
2275 call VerifyBoth(buf, "Test_diff_overlapped_3.24", "")
2276
2277 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["a", "c"])
2278 call VerifyBoth(buf, "Test_diff_overlapped_3.25", "")
2279
2280 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["a"])
2281 call VerifyBoth(buf, "Test_diff_overlapped_3.26", "")
2282
2283 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["b"])
2284 call VerifyBoth(buf, "Test_diff_overlapped_3.27", "")
2285
2286 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["d", "e"])
2287 call VerifyBoth(buf, "Test_diff_overlapped_3.28", "")
2288
2289 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["e"])
2290 call VerifyBoth(buf, "Test_diff_overlapped_3.29", "")
2291
2292 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "d", "e"])
2293 call VerifyBoth(buf, "Test_diff_overlapped_3.30", "")
2294
2295 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "e"])
2296 call VerifyBoth(buf, "Test_diff_overlapped_3.31", "")
2297
2298 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a"])
2299 call VerifyBoth(buf, "Test_diff_overlapped_3.32", "")
2300
2301 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "b", "d", "e"])
2302 call VerifyBoth(buf, "Test_diff_overlapped_3.33", "")
2303
2304 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "b", "e"])
2305 call VerifyBoth(buf, "Test_diff_overlapped_3.34", "")
2306
2307 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "b"])
2308 call VerifyBoth(buf, "Test_diff_overlapped_3.35", "")
2309
2310 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["a", "y", "b", "c"])
2311 call VerifyBoth(buf, "Test_diff_overlapped_3.36", "")
2312
2313 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["a", "b", "y", "c"])
2314 call VerifyBoth(buf, "Test_diff_overlapped_3.37", "")
2315
Yukihiro Nakadaira01f65092025-01-15 18:36:43 +01002316 call WriteDiffFiles3(buf, ["a", "b", "c"], ["d", "e"], ["b", "f"])
2317 call VerifyBoth(buf, "Test_diff_overlapped_3.38", "")
2318
2319 call WriteDiffFiles3(buf, ["a", "b", "c"], ["d", "e"], ["b"])
2320 call VerifyBoth(buf, "Test_diff_overlapped_3.39", "")
2321
Yee Cheng Chinbc08ceb2025-03-02 22:05:37 +01002322 " File 3 overlaps twice, 2nd overlap completely within the existing block.
2323 call WriteDiffFiles3(buf, ["foo", "a", "b", "c", "bar"], ["foo", "w", "x", "y", "z", "bar"], ["foo", "1", "a", "b", "2", "bar"])
2324 call VerifyBoth(buf, "Test_diff_overlapped_3.40", "")
2325
2326 " File 3 overlaps twice, 2nd overlap extends beyond existing block on new
2327 " side. Make sure we don't over-extend the range and hit 'bar'.
2328 call WriteDiffFiles3(buf, ["foo", "a", "b", "c", "d", "bar"], ["foo", "w", "x", "y", "z", "u", "bar"], ["foo", "1", "a", "b", "2", "d", "bar"])
2329 call VerifyBoth(buf, "Test_diff_overlapped_3.41", "")
2330
2331 " Chained overlaps. File 3's 2nd overlap spans two diff blocks and is longer
2332 " than the 2nd one.
2333 call WriteDiffFiles3(buf, ["foo", "a", "b", "c", "d", "e", "f", "bar"], ["foo", "w", "x", "y", "z", "e", "u", "bar"], ["foo", "1", "b", "2", "3", "d", "4", "f", "bar"])
2334 call VerifyBoth(buf, "Test_diff_overlapped_3.42", "")
2335
2336 " File 3 has 2 overlaps. An add and a delete. First overlap's expansion hits
2337 " the 2nd one. Make sure we adjust the diff block to have fewer lines.
2338 call WriteDiffFiles3(buf, ["foo", "a", "b", "bar"], ["foo", "x", "y", "bar"], ["foo", "1", "a", "bar"])
2339 call VerifyBoth(buf, "Test_diff_overlapped_3.43", "")
2340
2341 " File 3 has 2 overlaps. An add and another add. First overlap's expansion hits
2342 " the 2nd one. Make sure we adjust the diff block to have more lines.
2343 call WriteDiffFiles3(buf, ["foo", "a", "b", "c", "d", "bar"], ["foo", "w", "x", "y", "z", "u", "bar"], ["foo", "1", "a", "b", "3", "4", "d", "bar"])
2344 call VerifyBoth(buf, "Test_diff_overlapped_3.44", "")
2345
Yukihiro Nakadaira06fe70c2024-09-26 16:19:42 +02002346 call StopVimInTerminal(buf)
2347endfunc
2348
zeertzjq7c515282024-11-10 20:26:12 +01002349" switching windows in diff mode caused an unnecessary scroll
Christian Brabandt05a40e02024-10-29 20:29:04 +01002350func Test_diff_topline_noscroll()
2351 CheckScreendump
2352
2353 let content =<< trim END
2354 call setline(1, range(1,60))
2355 vnew
2356 call setline(1, range(1,10) + range(50,60))
2357 windo diffthis
2358 norm! G
2359 exe "norm! 30\<C-y>"
2360 END
2361 call writefile(content, 'Xcontent', 'D')
2362 let buf = RunVimInTerminal('-S Xcontent', {'rows': 20})
2363 call VerifyScreenDump(buf, 'Test_diff_topline_1', {})
2364 call term_sendkeys(buf, ":echo line('w0', 1001)\<cr>")
2365 call term_wait(buf)
2366 call VerifyScreenDump(buf, 'Test_diff_topline_2', {})
2367 call term_sendkeys(buf, "\<C-W>p")
2368 call term_wait(buf)
2369 call VerifyScreenDump(buf, 'Test_diff_topline_3', {})
2370 call term_sendkeys(buf, "\<C-W>p")
2371 call term_wait(buf)
2372 call VerifyScreenDump(buf, 'Test_diff_topline_4', {})
2373 call StopVimInTerminal(buf)
2374endfunc
2375
Yee Cheng Chin9943d472025-03-26 19:41:02 +01002376" Test inline highlighting which shows what's different within each diff block
2377func Test_diff_inline()
2378 CheckScreendump
2379
2380 call WriteDiffFiles(0, [], [])
2381 let buf = RunVimInTerminal('-d Xdifile1 Xdifile2', {})
2382 call term_sendkeys(buf, ":set autoread\<CR>\<c-w>w:set autoread\<CR>\<c-w>w")
2383
2384 call WriteDiffFiles(buf, ["abcdef ghi jk n", "x", "y"], ["aBcef gHi lm n", "y", "z"])
2385 call VerifyInternal(buf, "Test_diff_inline_01", "")
2386 call VerifyInternal(buf, "Test_diff_inline_02", " diffopt+=inline:none")
2387
2388 " inline:simple is the same as default
2389 call VerifyInternal(buf, "Test_diff_inline_01", " diffopt+=inline:simple")
2390
2391 call VerifyInternal(buf, "Test_diff_inline_03", " diffopt+=inline:char")
2392 call VerifyInternal(buf, "Test_diff_inline_04", " diffopt+=inline:word")
2393
2394 " multiple inline values will the last one
2395 call VerifyInternal(buf, "Test_diff_inline_01", " diffopt+=inline:none,inline:char,inline:simple")
2396 call VerifyInternal(buf, "Test_diff_inline_02", " diffopt+=inline:simple,inline:word,inline:none")
2397 call VerifyInternal(buf, "Test_diff_inline_03", " diffopt+=inline:simple,inline:word,inline:char")
2398
2399 " DiffTextAdd highlight
2400 call term_sendkeys(buf, ":hi DiffTextAdd ctermbg=blue\<CR>")
2401 call VerifyInternal(buf, "Test_diff_inline_05", " diffopt+=inline:char")
2402
2403 " Live update in insert mode
2404 call term_sendkeys(buf, "\<Esc>isometext")
2405 call VerifyScreenDump(buf, "Test_diff_inline_06", {})
2406 call term_sendkeys(buf, "\<Esc>u")
2407
2408 " icase simple scenarios
2409 call VerifyInternal(buf, "Test_diff_inline_07", " diffopt+=inline:simple,icase")
2410 call VerifyInternal(buf, "Test_diff_inline_08", " diffopt+=inline:char,icase")
2411 call VerifyInternal(buf, "Test_diff_inline_09", " diffopt+=inline:word,icase")
2412
2413 " diff algorithms should affect highlight
2414 call WriteDiffFiles(buf, ["apples and oranges"], ["oranges and apples"])
2415 call VerifyInternal(buf, "Test_diff_inline_10", " diffopt+=inline:char")
2416 call VerifyInternal(buf, "Test_diff_inline_11", " diffopt+=inline:char,algorithm:patience")
2417
2418 " icase: composing chars and Unicode fold case edge cases
2419 call WriteDiffFiles(buf,
2420 \ ["1 - sigma in 6σ and Ὀδυσσεύς", "1 - angstrom in åå", "1 - composing: ii⃗I⃗"],
2421 \ ["2 - Sigma in 6Σ and ὈΔΥΣΣΕΎΣ", "2 - Angstrom in ÅÅ", "2 - Composing: i⃗I⃗I⃗"])
2422 call VerifyInternal(buf, "Test_diff_inline_12", " diffopt+=inline:char")
2423 call VerifyInternal(buf, "Test_diff_inline_13", " diffopt+=inline:char,icase")
2424
2425 " wide chars
2426 call WriteDiffFiles(buf, ["abc😅xde一", "f🚀g"], ["abcy😢de", "二f🚀g"])
2427 call VerifyInternal(buf, "Test_diff_inline_14", " diffopt+=inline:char,icase")
2428
2429 " NUL char (\n below is internally substituted as NUL)
2430 call WriteDiffFiles(buf, ["1\n34\n5\n6"], ["1234\n5", "6"])
2431 call VerifyInternal(buf, "Test_diff_inline_15", " diffopt+=inline:char")
2432
2433 " word diff: always use first buffer's iskeyword and ignore others' for consistency
2434 call WriteDiffFiles(buf, ["foo+bar test"], ["foo+baz test"])
2435 call VerifyInternal(buf, "Test_diff_inline_word_01", " diffopt+=inline:word")
2436
2437 call term_sendkeys(buf, ":set iskeyword+=+\<CR>:diffupdate\<CR>")
2438 call VerifyInternal(buf, "Test_diff_inline_word_02", " diffopt+=inline:word")
2439
2440 call term_sendkeys(buf, ":set iskeyword&\<CR>:wincmd w\<CR>")
2441 call term_sendkeys(buf, ":set iskeyword+=+\<CR>:wincmd w\<CR>:diffupdate\<CR>")
2442 " Use the previous screen dump as 2nd buffer's iskeyword does not matter
2443 call VerifyInternal(buf, "Test_diff_inline_word_01", " diffopt+=inline:word")
2444
2445 call term_sendkeys(buf, ":windo set iskeyword&\<CR>:1wincmd w\<CR>")
2446
Yee Cheng Chin9aa120f2025-04-04 19:16:21 +02002447 " word diff: test handling of multi-byte characters. Only alphanumeric chars
2448 " (e.g. Greek alphabet, but not CJK/emoji) count as words.
2449 call WriteDiffFiles(buf, ["🚀⛵️一二三ひらがなΔέλτα Δelta foobar"], ["🚀🛸一二四ひらなδέλτα δelta foobar"])
2450 call VerifyInternal(buf, "Test_diff_inline_word_03", " diffopt+=inline:word")
2451
Yee Cheng Chin9943d472025-03-26 19:41:02 +01002452 " char diff: should slide highlight to whitespace boundary if possible for
2453 " better readability (by using forced indent-heuristics). A wrong result
2454 " would be if the highlight is "Bar, prefix". It should be "prefixBar, "
2455 " instead.
2456 call WriteDiffFiles(buf, ["prefixFoo, prefixEnd"], ["prefixFoo, prefixBar, prefixEnd"])
2457 call VerifyInternal(buf, "Test_diff_inline_char_01", " diffopt+=inline:char")
2458
2459 " char diff: small gaps between inline diff blocks will be merged during refine step
2460 " - first segment: test that we iteratively merge small gaps after we merged
2461 " adjacent blocks, but only with limited number (set to 4) of iterations.
2462 " - second and third segments: show that we need a large enough adjacent block to
2463 " trigger a merge.
2464 " - fourth segment: small gaps are not merged when adjacent large block is
2465 " on a different line.
2466 call WriteDiffFiles(buf,
2467 \ ["abcdefghijklmno", "anchor1",
2468 \ "abcdefghijklmno", "anchor2",
2469 \ "abcdefghijklmno", "anchor3",
2470 \ "test", "multiline"],
zeertzjq5a307c32025-03-28 19:01:32 +01002471 \ ["a?c?e?g?i?k???o", "anchor1",
2472 \ "a??de?????klmno", "anchor2",
Yee Cheng Chin9943d472025-03-26 19:41:02 +01002473 \ "a??de??????lmno", "anchor3",
2474 \ "t?s?", "??????i?e"])
2475 call VerifyInternal(buf, "Test_diff_inline_char_02", " diffopt+=inline:char")
2476
2477 " Test multi-line blocks and whitespace
2478 call WriteDiffFiles(buf,
2479 \ ["this is ", "sometest text foo", "baz abc def ", "one", "word another word", "additional line"],
2480 \ ["this is some test", "texts", "foo bar abX Yef ", "oneword another word"])
2481 call VerifyInternal(buf, "Test_diff_inline_multiline_01", " diffopt+=inline:char,iwhite")
2482 call VerifyInternal(buf, "Test_diff_inline_multiline_02", " diffopt+=inline:word,iwhite")
2483 call VerifyInternal(buf, "Test_diff_inline_multiline_03", " diffopt+=inline:char,iwhiteeol")
2484 call VerifyInternal(buf, "Test_diff_inline_multiline_04", " diffopt+=inline:word,iwhiteeol")
2485 call VerifyInternal(buf, "Test_diff_inline_multiline_05", " diffopt+=inline:char,iwhiteall")
2486 call VerifyInternal(buf, "Test_diff_inline_multiline_06", " diffopt+=inline:word,iwhiteall")
2487
2488 " newline should be highlighted too when 'list' is set
2489 call term_sendkeys(buf, ":windo set list\<CR>")
2490 call VerifyInternal(buf, "Test_diff_inline_multiline_07", " diffopt+=inline:char")
2491 call VerifyInternal(buf, "Test_diff_inline_multiline_08", " diffopt+=inline:char,iwhite")
2492 call VerifyInternal(buf, "Test_diff_inline_multiline_09", " diffopt+=inline:char,iwhiteeol")
2493 call VerifyInternal(buf, "Test_diff_inline_multiline_10", " diffopt+=inline:char,iwhiteall")
2494 call term_sendkeys(buf, ":windo set nolist\<CR>")
2495
2496 call StopVimInTerminal(buf)
2497endfunc
2498
2499func Test_diff_inline_multibuffer()
2500 CheckScreendump
2501
2502 call WriteDiffFiles3(0, [], [], [])
2503 let buf = RunVimInTerminal('-d Xdifile1 Xdifile2 Xdifile3', {})
2504 call term_sendkeys(buf, ":windo set autoread\<CR>:1wincmd w\<CR>")
2505 call term_sendkeys(buf, ":hi DiffTextAdd ctermbg=blue\<CR>")
2506
2507 call WriteDiffFiles3(buf,
2508 \ ["That is buffer1.", "anchor", "Some random text", "anchor"],
2509 \ ["This is buffer2.", "anchor", "Some text", "anchor", "buffer2/3"],
2510 \ ["This is buffer3. Last.", "anchor", "Some more", "text here.", "anchor", "only in buffer2/3", "not in buffer1"])
2511 call VerifyInternal(buf, "Test_diff_inline_multibuffer_01", " diffopt+=inline:char")
2512
zeertzjq5a307c32025-03-28 19:01:32 +01002513 " Close one of the buffers and make sure it updates correctly
Yee Cheng Chin9943d472025-03-26 19:41:02 +01002514 call term_sendkeys(buf, ":diffoff\<CR>")
2515 call VerifyInternal(buf, "Test_diff_inline_multibuffer_02", " diffopt+=inline:char")
2516
2517 " Update text in the non-diff buffer and nothing should be changed
2518 call term_sendkeys(buf, "\<Esc>isometext")
2519 call VerifyScreenDump(buf, "Test_diff_inline_multibuffer_03", {})
2520 call term_sendkeys(buf, "\<Esc>u")
2521
2522 call term_sendkeys(buf, ":diffthis\<CR>")
2523 call VerifyInternal(buf, "Test_diff_inline_multibuffer_01", " diffopt+=inline:char")
2524
2525 " Test that removing first buffer from diff will in turn use the next
2526 " earliest buffer's iskeyword during word diff.
2527 call WriteDiffFiles3(buf,
2528 \ ["This+is=a-setence"],
2529 \ ["This+is=another-setence"],
2530 \ ["That+is=a-setence"])
2531 call term_sendkeys(buf, ":set iskeyword+=+\<CR>:2wincmd w\<CR>:set iskeyword+=-\<CR>:1wincmd w\<CR>")
2532 call VerifyInternal(buf, "Test_diff_inline_multibuffer_04", " diffopt+=inline:word")
2533 call term_sendkeys(buf, ":diffoff\<CR>")
2534 call VerifyInternal(buf, "Test_diff_inline_multibuffer_05", " diffopt+=inline:word")
2535 call term_sendkeys(buf, ":diffthis\<CR>")
2536 call VerifyInternal(buf, "Test_diff_inline_multibuffer_04", " diffopt+=inline:word")
2537
2538 " Test multi-buffer char diff refinement, and that removing a buffer from
2539 " diff will update the others properly.
2540 call WriteDiffFiles3(buf,
2541 \ ["abcdefghijkYmYYY"],
2542 \ ["aXXdXXghijklmnop"],
2543 \ ["abcdefghijkYmYop"])
2544 call VerifyInternal(buf, "Test_diff_inline_multibuffer_06", " diffopt+=inline:char")
2545 call term_sendkeys(buf, ":diffoff\<CR>")
2546 call VerifyInternal(buf, "Test_diff_inline_multibuffer_07", " diffopt+=inline:char")
2547 call term_sendkeys(buf, ":diffthis\<CR>")
2548 call VerifyInternal(buf, "Test_diff_inline_multibuffer_06", " diffopt+=inline:char")
2549
2550 call StopVimInTerminal(buf)
2551endfunc
2552
Jonathon7c7a4e62025-01-12 09:58:00 +01002553func Test_diffget_diffput_linematch()
2554 CheckScreendump
2555 call delete('.Xdifile1.swp')
2556 call delete('.Xdifile2.swp')
2557 call WriteDiffFiles(0, [], [])
2558 let buf = RunVimInTerminal('-d Xdifile1 Xdifile2', {})
2559 call term_sendkeys(buf, ":set autoread\<CR>\<c-w>w:set autoread\<CR>\<c-w>w")
2560
2561 " enable linematch
2562 call term_sendkeys(buf, ":set diffopt+=linematch:30\<CR>")
2563 call WriteDiffFiles(buf, ['',
2564 \ 'common line',
2565 \ 'common line',
2566 \ '',
2567 \ 'ABCabc',
2568 \ 'ABCabc',
2569 \ 'ABCabc',
2570 \ 'ABCabc',
2571 \ 'common line',
2572 \ 'common line',
2573 \ 'common line',
2574 \ 'something' ],
2575 \ ['',
2576 \ 'common line',
2577 \ 'common line',
2578 \ '',
2579 \ 'DEFabc',
2580 \ 'xyz',
2581 \ 'xyz',
2582 \ 'xyz',
2583 \ 'DEFabc',
2584 \ 'DEFabc',
2585 \ 'DEFabc',
2586 \ 'common line',
2587 \ 'common line',
2588 \ 'DEF',
2589 \ 'common line',
2590 \ 'DEF',
2591 \ 'something'])
2592 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_1', {})
2593
2594 " get from window 1 from line 5 to 9
2595 call term_sendkeys(buf, "1\<c-w>w")
2596 call term_sendkeys(buf, ":5,9diffget\<CR>")
2597 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_2', {})
2598
2599 " undo the last diffget
2600 call term_sendkeys(buf, "u")
2601
2602 " get from window 2 from line 5 to 10
2603 call term_sendkeys(buf, "2\<c-w>w")
2604 call term_sendkeys(buf, ":5,10diffget\<CR>")
2605 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_3', {})
2606
2607 " undo the last diffget
2608 call term_sendkeys(buf, "u")
2609
2610 " get all from window 2
2611 call term_sendkeys(buf, "2\<c-w>w")
2612 call term_sendkeys(buf, ":4,17diffget\<CR>")
2613 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_4', {})
2614
2615 " undo the last diffget
2616 call term_sendkeys(buf, "u")
2617
2618 " get all from window 1
2619 call term_sendkeys(buf, "1\<c-w>w")
2620 call term_sendkeys(buf, ":4,12diffget\<CR>")
2621 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_5', {})
2622
2623 " undo the last diffget
2624 call term_sendkeys(buf, "u")
2625
2626 " get from window 1 using do 1 line 5
2627 call term_sendkeys(buf, "1\<c-w>w")
2628 call term_sendkeys(buf, "5gg")
2629 call term_sendkeys(buf, ":diffget\<CR>")
2630 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_6', {})
2631
2632 " undo the last diffget
2633 call term_sendkeys(buf, "u")
2634
2635 " get from window 1 using do 2 line 6
2636 call term_sendkeys(buf, "1\<c-w>w")
2637 call term_sendkeys(buf, "6gg")
2638 call term_sendkeys(buf, ":diffget\<CR>")
2639 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_7', {})
2640
2641 " undo the last diffget
2642 call term_sendkeys(buf, "u")
2643
2644 " get from window 1 using do 2 line 7
2645 call term_sendkeys(buf, "1\<c-w>w")
2646 call term_sendkeys(buf, "7gg")
2647 call term_sendkeys(buf, ":diffget\<CR>")
2648 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_8', {})
2649
2650 " undo the last diffget
2651 call term_sendkeys(buf, "u")
2652
2653 " get from window 1 using do 2 line 11
2654 call term_sendkeys(buf, "1\<c-w>w")
2655 call term_sendkeys(buf, "11gg")
2656 call term_sendkeys(buf, ":diffget\<CR>")
2657 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_9', {})
2658
2659 " undo the last diffget
2660 call term_sendkeys(buf, "u")
2661
2662 " get from window 1 using do 2 line 12
2663 call term_sendkeys(buf, "1\<c-w>w")
2664 call term_sendkeys(buf, "12gg")
2665 call term_sendkeys(buf, ":diffget\<CR>")
2666 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_10', {})
2667
2668 " undo the last diffget
2669 call term_sendkeys(buf, "u")
2670
2671 " put from window 1 using dp 1 line 5
2672 call term_sendkeys(buf, "1\<c-w>w")
2673 call term_sendkeys(buf, "5gg")
2674 call term_sendkeys(buf, ":diffput\<CR>")
2675 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_11', {})
2676
2677 " undo the last diffput
2678 call term_sendkeys(buf, "2\<c-w>w")
2679 call term_sendkeys(buf, "u")
2680
2681 " put from window 1 using dp 2 line 6
2682 call term_sendkeys(buf, "1\<c-w>w")
2683 call term_sendkeys(buf, "6gg")
2684 call term_sendkeys(buf, ":diffput\<CR>")
2685 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_12', {})
2686
2687 " undo the last diffput
2688 call term_sendkeys(buf, "2\<c-w>w")
2689 call term_sendkeys(buf, "u")
2690
2691 " put from window 1 using dp 2 line 7
2692 call term_sendkeys(buf, "1\<c-w>w")
2693 call term_sendkeys(buf, "7gg")
2694 call term_sendkeys(buf, ":diffput\<CR>")
2695 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_13', {})
2696
2697 " undo the last diffput
2698 call term_sendkeys(buf, "2\<c-w>w")
2699 call term_sendkeys(buf, "u")
2700
2701 " put from window 1 using dp 2 line 11
2702 call term_sendkeys(buf, "1\<c-w>w")
2703 call term_sendkeys(buf, "11gg")
2704 call term_sendkeys(buf, ":diffput\<CR>")
2705 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_14', {})
2706
2707 " undo the last diffput
2708 call term_sendkeys(buf, "2\<c-w>w")
2709 call term_sendkeys(buf, "u")
2710
2711 " put from window 1 using dp 2 line 12
2712 call term_sendkeys(buf, "1\<c-w>w")
2713 call term_sendkeys(buf, "12gg")
2714 call term_sendkeys(buf, ":diffput\<CR>")
2715 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_15', {})
2716
2717 " undo the last diffput
2718 call term_sendkeys(buf, "2\<c-w>w")
2719 call term_sendkeys(buf, "u")
2720
2721 " put from window 2 using dp line 6
2722 call term_sendkeys(buf, "2\<c-w>w")
2723 call term_sendkeys(buf, "6gg")
2724 call term_sendkeys(buf, ":diffput\<CR>")
2725 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_16', {})
2726
2727 " undo the last diffput
2728 call term_sendkeys(buf, "1\<c-w>w")
2729 call term_sendkeys(buf, "u")
2730
2731 " put from window 2 using dp line 8
2732 call term_sendkeys(buf, "2\<c-w>w")
2733 call term_sendkeys(buf, "8gg")
2734 call term_sendkeys(buf, ":diffput\<CR>")
2735 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_17', {})
2736
2737 " undo the last diffput
2738 call term_sendkeys(buf, "1\<c-w>w")
2739 call term_sendkeys(buf, "u")
2740
2741 " put from window 2 using dp line 9
2742 call term_sendkeys(buf, "2\<c-w>w")
2743 call term_sendkeys(buf, "9gg")
2744 call term_sendkeys(buf, ":diffput\<CR>")
2745 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_18', {})
2746
2747 " undo the last diffput
2748 call term_sendkeys(buf, "1\<c-w>w")
2749 call term_sendkeys(buf, "u")
2750
2751 " put from window 2 using dp line 17
2752 call term_sendkeys(buf, "2\<c-w>w")
2753 call term_sendkeys(buf, "17gg")
2754 call term_sendkeys(buf, ":diffput\<CR>")
2755 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_19', {})
Jonathonca307ef2025-01-17 13:37:35 +01002756 " clean up
2757 call StopVimInTerminal(buf)
Jonathon7c7a4e62025-01-12 09:58:00 +01002758endfunc
2759
2760func Test_linematch_diff()
2761 CheckScreendump
2762 call delete('.Xdifile1.swp')
2763 call delete('.Xdifile2.swp')
2764 call WriteDiffFiles(0, [], [])
2765 let buf = RunVimInTerminal('-d Xdifile1 Xdifile2', {})
2766 call term_sendkeys(buf, ":set autoread\<CR>\<c-w>w:set autoread\<CR>\<c-w>w")
2767
2768 " enable linematch
2769 call term_sendkeys(buf, ":set diffopt+=linematch:30\<CR>")
2770 call WriteDiffFiles(buf, ['// abc d?',
2771 \ '// d?',
2772 \ '// d?' ],
2773 \ ['!',
2774 \ 'abc d!',
2775 \ 'd!'])
2776 call VerifyScreenDump(buf, 'Test_linematch_diff1', {})
Jonathonca307ef2025-01-17 13:37:35 +01002777 " clean up
2778 call StopVimInTerminal(buf)
Jonathon7c7a4e62025-01-12 09:58:00 +01002779endfunc
2780
2781func Test_linematch_diff_iwhite()
2782 CheckScreendump
2783 call delete('.Xdifile1.swp')
2784 call delete('.Xdifile2.swp')
2785 call WriteDiffFiles(0, [], [])
2786 let buf = RunVimInTerminal('-d Xdifile1 Xdifile2', {})
2787 call term_sendkeys(buf, ":set autoread\<CR>\<c-w>w:set autoread\<CR>\<c-w>w")
2788
2789 " setup a diff with 2 files and set linematch:30, with ignore white
2790 call term_sendkeys(buf, ":set diffopt+=linematch:30\<CR>")
2791 call WriteDiffFiles(buf, ['void testFunction () {',
2792 \ ' for (int i = 0; i < 10; i++) {',
2793 \ ' for (int j = 0; j < 10; j++) {',
2794 \ ' }',
2795 \ ' }',
2796 \ '}' ],
2797 \ ['void testFunction () {',
2798 \ ' // for (int j = 0; j < 10; i++) {',
2799 \ ' // }',
2800 \ '}'])
2801 call VerifyScreenDump(buf, 'Test_linematch_diff_iwhite1', {})
2802 call term_sendkeys(buf, ":set diffopt+=iwhiteall\<CR>")
2803 call VerifyScreenDump(buf, 'Test_linematch_diff_iwhite2', {})
Jonathonca307ef2025-01-17 13:37:35 +01002804 " clean up
2805 call StopVimInTerminal(buf)
Jonathon7c7a4e62025-01-12 09:58:00 +01002806endfunc
2807
2808func Test_linematch_diff_grouping()
2809 CheckScreendump
2810 call delete('.Xdifile1.swp')
2811 call delete('.Xdifile2.swp')
2812 call WriteDiffFiles(0, [], [])
2813 let buf = RunVimInTerminal('-d Xdifile1 Xdifile2', {})
2814 call term_sendkeys(buf, ":set autoread\<CR>\<c-w>w:set autoread\<CR>\<c-w>w")
2815
2816 " a diff that would result in multiple groups before grouping optimization
2817 call term_sendkeys(buf, ":set diffopt+=linematch:30\<CR>")
2818 call WriteDiffFiles(buf, ['!A',
2819 \ '!B',
2820 \ '!C' ],
2821 \ ['?Z',
2822 \ '?A',
2823 \ '?B',
2824 \ '?C',
2825 \ '?A',
2826 \ '?B',
2827 \ '?B',
2828 \ '?C'])
2829 call VerifyScreenDump(buf, 'Test_linematch_diff_grouping1', {})
2830 call WriteDiffFiles(buf, ['!A',
2831 \ '!B',
2832 \ '!C' ],
2833 \ ['?A',
2834 \ '?Z',
2835 \ '?B',
2836 \ '?C',
2837 \ '?A',
2838 \ '?B',
2839 \ '?C',
2840 \ '?C'])
2841 call VerifyScreenDump(buf, 'Test_linematch_diff_grouping2', {})
Jonathonca307ef2025-01-17 13:37:35 +01002842 " clean up
2843 call StopVimInTerminal(buf)
Jonathon7c7a4e62025-01-12 09:58:00 +01002844endfunc
2845
2846func Test_linematch_diff_scroll()
2847 CheckScreendump
2848 call delete('.Xdifile1.swp')
2849 call delete('.Xdifile2.swp')
2850 call WriteDiffFiles(0, [], [])
2851 let buf = RunVimInTerminal('-d Xdifile1 Xdifile2', {})
2852 call term_sendkeys(buf, ":set autoread\<CR>\<c-w>w:set autoread\<CR>\<c-w>w")
2853
2854 " a diff that would result in multiple groups before grouping optimization
2855 call term_sendkeys(buf, ":set diffopt+=linematch:30\<CR>")
2856 call WriteDiffFiles(buf, ['!A',
2857 \ '!B',
2858 \ '!C' ],
2859 \ ['?A',
2860 \ '?Z',
2861 \ '?B',
2862 \ '?C',
2863 \ '?A',
2864 \ '?B',
2865 \ '?C',
2866 \ '?C'])
2867 " scroll down to show calculation of top fill and scroll to correct line in
2868 " both windows
2869 call VerifyScreenDump(buf, 'Test_linematch_diff_grouping_scroll0', {})
2870 call term_sendkeys(buf, "3\<c-e>")
2871 call VerifyScreenDump(buf, 'Test_linematch_diff_grouping_scroll1', {})
2872 call term_sendkeys(buf, "3\<c-e>")
2873 call VerifyScreenDump(buf, 'Test_linematch_diff_grouping_scroll2', {})
Jonathonca307ef2025-01-17 13:37:35 +01002874 " clean up
2875 call StopVimInTerminal(buf)
Jonathon7c7a4e62025-01-12 09:58:00 +01002876endfunc
2877
Jonathon7c7a4e62025-01-12 09:58:00 +01002878func Test_linematch_line_limit_exceeded()
2879 CheckScreendump
2880 call delete('.Xdifile1.swp')
2881 call delete('.Xdifile2.swp')
2882 call WriteDiffFiles(0, [], [])
2883 let buf = RunVimInTerminal('-d Xdifile1 Xdifile2', {})
2884 call term_sendkeys(buf, ":set autoread\<CR>\<c-w>w:set autoread\<CR>\<c-w>w")
2885
2886 call term_sendkeys(buf, ":set diffopt+=linematch:10\<CR>")
2887 " a diff block will not be aligned with linematch because it's contents
2888 " exceed 10 lines
2889 call WriteDiffFiles(buf,
2890 \ ['common line',
2891 \ 'HIL',
2892 \ '',
2893 \ 'aABCabc',
2894 \ 'aABCabc',
2895 \ 'aABCabc',
2896 \ 'aABCabc',
2897 \ 'common line',
2898 \ 'HIL',
2899 \ 'common line',
2900 \ 'something'],
2901 \ ['common line',
2902 \ 'DEF',
2903 \ 'GHI',
2904 \ 'something',
2905 \ '',
2906 \ 'aDEFabc',
2907 \ 'xyz',
2908 \ 'xyz',
2909 \ 'xyz',
2910 \ 'aDEFabc',
2911 \ 'aDEFabc',
2912 \ 'aDEFabc',
2913 \ 'common line',
2914 \ 'DEF',
2915 \ 'GHI',
2916 \ 'something else',
2917 \ 'common line',
2918 \ 'something'])
2919 call VerifyScreenDump(buf, 'Test_linematch_line_limit_exceeded1', {})
2920 " after increasing the count to 30, the limit is not exceeded, and the
2921 " alignment algorithm will run on the largest diff block here
2922 call term_sendkeys(buf, ":set diffopt+=linematch:30\<CR>")
2923 call VerifyScreenDump(buf, 'Test_linematch_line_limit_exceeded2', {})
Jonathonca307ef2025-01-17 13:37:35 +01002924 " clean up
2925 call StopVimInTerminal(buf)
Jonathon7c7a4e62025-01-12 09:58:00 +01002926endfunc
2927
2928func Test_linematch_3diffs()
2929 CheckScreendump
2930 call delete('.Xdifile1.swp')
2931 call delete('.Xdifile2.swp')
2932 call delete('.Xdifile3.swp')
2933 call WriteDiffFiles3(0, [], [], [])
2934 let buf = RunVimInTerminal('-d Xdifile1 Xdifile2 Xdifile3', {})
2935 call term_sendkeys(buf, "1\<c-w>w:set autoread\<CR>")
2936 call term_sendkeys(buf, "2\<c-w>w:set autoread\<CR>")
2937 call term_sendkeys(buf, "3\<c-w>w:set autoread\<CR>")
2938 call term_sendkeys(buf, ":set diffopt+=linematch:30\<CR>")
2939 call WriteDiffFiles3(buf,
2940 \ ["",
2941 \ " common line",
2942 \ " AAA",
2943 \ " AAA",
2944 \ " AAA"],
2945 \ ["",
2946 \ " common line",
2947 \ " <<<<<<< HEAD",
2948 \ " AAA",
2949 \ " AAA",
2950 \ " AAA",
2951 \ " =======",
2952 \ " BBB",
2953 \ " BBB",
2954 \ " BBB",
2955 \ " >>>>>>> branch1"],
2956 \ ["",
2957 \ " common line",
2958 \ " BBB",
2959 \ " BBB",
2960 \ " BBB"])
2961 call VerifyScreenDump(buf, 'Test_linematch_3diffs1', {})
Jonathonca307ef2025-01-17 13:37:35 +01002962 " clean up
2963 call StopVimInTerminal(buf)
2964endfunc
Jonathon7c7a4e62025-01-12 09:58:00 +01002965
Jonathonca307ef2025-01-17 13:37:35 +01002966" this used to access invalid memory
2967func Test_linematch_3diffs_sanity_check()
2968 CheckScreendump
2969 call delete('.Xfile_linematch1.swp')
2970 call delete('.Xfile_linematch2.swp')
2971 call delete('.Xfile_linematch3.swp')
2972 let lines =<< trim END
2973 set diffopt+=linematch:60
2974 call feedkeys("Aq\<esc>")
2975 call feedkeys("GAklm\<esc>")
2976 call feedkeys("o")
2977 END
2978 call writefile(lines, 'Xlinematch_3diffs.vim', 'D')
2979 call writefile(['abcd', 'def', 'hij'], 'Xfile_linematch1', 'D')
2980 call writefile(['defq', 'hijk', 'nopq'], 'Xfile_linematch2', 'D')
2981 call writefile(['hijklm', 'nopqr', 'stuv'], 'Xfile_linematch3', 'D')
2982 call WriteDiffFiles3(0, [], [], [])
2983 let buf = RunVimInTerminal('-d -S Xlinematch_3diffs.vim Xfile_linematch1 Xfile_linematch2 Xfile_linematch3', {})
2984 call VerifyScreenDump(buf, 'Test_linematch_3diffs2', {})
2985
2986 " clean up
2987 call StopVimInTerminal(buf)
Jonathon7c7a4e62025-01-12 09:58:00 +01002988endfunc
Bram Moolenaar8dfcce32020-03-18 19:32:26 +01002989" vim: shiftwidth=2 sts=2 expandtab