blob: dadffecb5641b18241c393fd84b45f10b5323da4 [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)
Drew Vogelea67ba72025-05-07 22:05:17 +0200882 CheckScreendump
883
Bram Moolenaare828b762018-09-10 17:51:58 +0200884 " trailing : for leaving the cursor on the command line
Bram Moolenaar785fc652018-09-15 19:17:38 +0200885 for cmd in [":set diffopt=filler" . a:extra . "\<CR>:", ":set diffopt+=internal\<CR>:"]
Bram Moolenaare828b762018-09-10 17:51:58 +0200886 call term_sendkeys(a:buf, cmd)
887 if VerifyScreenDump(a:buf, a:dumpfile, {}, cmd =~ 'internal' ? 'internal' : 'external')
Bram Moolenaar485b6272021-05-18 19:19:03 +0200888 " don't let the next iteration overwrite the "failed" file.
889 return
Bram Moolenaare828b762018-09-10 17:51:58 +0200890 endif
891 endfor
Bram Moolenaar485b6272021-05-18 19:19:03 +0200892
893 " also test unified diff
894 call term_sendkeys(a:buf, ":call SetupUnified()\<CR>:")
glacambread5c1782021-05-24 14:20:53 +0200895 call term_sendkeys(a:buf, ":redraw!\<CR>:")
Bram Moolenaar485b6272021-05-18 19:19:03 +0200896 call VerifyScreenDump(a:buf, a:dumpfile, {}, 'unified')
897 call term_sendkeys(a:buf, ":call StopUnified()\<CR>:")
Bram Moolenaare828b762018-09-10 17:51:58 +0200898endfunc
899
Bram Moolenaar785fc652018-09-15 19:17:38 +0200900" Verify a screendump with the internal diff only.
901func VerifyInternal(buf, dumpfile, extra)
Drew Vogelea67ba72025-05-07 22:05:17 +0200902 CheckScreendump
903
Bram Moolenaar785fc652018-09-15 19:17:38 +0200904 call term_sendkeys(a:buf, ":diffupdate!\<CR>")
905 " trailing : for leaving the cursor on the command line
906 call term_sendkeys(a:buf, ":set diffopt=internal,filler" . a:extra . "\<CR>:")
907 call VerifyScreenDump(a:buf, a:dumpfile, {})
908endfunc
909
Bram Moolenaare828b762018-09-10 17:51:58 +0200910func Test_diff_screen()
Yee Cheng Chin49f2ba62024-02-14 20:34:58 +0100911 if has('osxdarwin') && system('diff --version') =~ '^Apple diff'
912 throw 'Skipped: unified diff does not work properly on this macOS version'
rhysde93d5ca2024-02-01 21:22:14 +0100913 endif
914
Bram Moolenaarf08b0eb2021-10-16 13:00:14 +0100915 let g:test_is_flaky = 1
Bram Moolenaar3c8ee622019-08-03 22:55:50 +0200916 CheckScreendump
917 CheckFeature menu
918
Bram Moolenaar485b6272021-05-18 19:19:03 +0200919 let lines =<< trim END
920 func UnifiedDiffExpr()
921 " Prepend some text to check diff type detection
922 call writefile(['warning', ' message'], v:fname_out)
glacambread5c1782021-05-24 14:20:53 +0200923 silent exe '!diff -U0 ' .. v:fname_in .. ' ' .. v:fname_new .. '>>' .. v:fname_out
Bram Moolenaar485b6272021-05-18 19:19:03 +0200924 endfunc
925 func SetupUnified()
926 set diffexpr=UnifiedDiffExpr()
glacambread5c1782021-05-24 14:20:53 +0200927 diffupdate
Bram Moolenaar485b6272021-05-18 19:19:03 +0200928 endfunc
929 func StopUnified()
930 set diffexpr=
931 endfunc
932 END
Bram Moolenaar59173412022-09-20 22:01:33 +0100933 call writefile(lines, 'XdiffSetup', 'D')
Bram Moolenaar485b6272021-05-18 19:19:03 +0200934
Bram Moolenaare828b762018-09-10 17:51:58 +0200935 " clean up already existing swap files, just in case
Bram Moolenaar61abe7d2022-08-30 21:46:08 +0100936 call delete('.Xdifile1.swp')
937 call delete('.Xdifile2.swp')
Bram Moolenaare828b762018-09-10 17:51:58 +0200938
939 " Test 1: Add a line in beginning of file 2
Bram Moolenaar785fc652018-09-15 19:17:38 +0200940 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 +0100941 let buf = RunVimInTerminal('-d -S XdiffSetup Xdifile1 Xdifile2', {})
Bram Moolenaar8ee4c012019-03-29 18:08:18 +0100942 " Set autoread mode, so that Vim won't complain once we re-write the test
Bram Moolenaare828b762018-09-10 17:51:58 +0200943 " files
Bram Moolenaar785fc652018-09-15 19:17:38 +0200944 call term_sendkeys(buf, ":set autoread\<CR>\<c-w>w:set autoread\<CR>\<c-w>w")
Bram Moolenaare828b762018-09-10 17:51:58 +0200945
946 call VerifyBoth(buf, 'Test_diff_01', '')
947
948 " Test 2: Add a line in beginning of file 1
Bram Moolenaar785fc652018-09-15 19:17:38 +0200949 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 +0200950 call VerifyBoth(buf, 'Test_diff_02', '')
951
952 " Test 3: Add a line at the end of file 2
Bram Moolenaar785fc652018-09-15 19:17:38 +0200953 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 +0200954 call VerifyBoth(buf, 'Test_diff_03', '')
955
956 " Test 4: Add a line 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, 5, 6, 7, 8, 9, 10])
Bram Moolenaare828b762018-09-10 17:51:58 +0200958 call VerifyBoth(buf, 'Test_diff_04', '')
959
960 " 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 +0200961 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 +0200962 call VerifyBoth(buf, 'Test_diff_05', '')
963
964 " 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 +0200965 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 +0200966 call VerifyBoth(buf, 'Test_diff_06', '')
967
Bram Moolenaarb9ddda62019-02-19 23:00:50 +0100968 " Variants on test 6 with different context settings
969 call term_sendkeys(buf, ":set diffopt+=context:2\<cr>")
970 call VerifyScreenDump(buf, 'Test_diff_06.2', {})
971 call term_sendkeys(buf, ":set diffopt-=context:2\<cr>")
972 call term_sendkeys(buf, ":set diffopt+=context:1\<cr>")
973 call VerifyScreenDump(buf, 'Test_diff_06.1', {})
974 call term_sendkeys(buf, ":set diffopt-=context:1\<cr>")
975 call term_sendkeys(buf, ":set diffopt+=context:0\<cr>")
976 call VerifyScreenDump(buf, 'Test_diff_06.0', {})
977 call term_sendkeys(buf, ":set diffopt-=context:0\<cr>")
978
Bram Moolenaare828b762018-09-10 17:51:58 +0200979 " Test 7 - 9: Test normal/patience/histogram diff algorithm
Bram Moolenaar785fc652018-09-15 19:17:38 +0200980 call WriteDiffFiles(buf, ['#include <stdio.h>', '', '// Frobs foo heartily', 'int frobnitz(int foo)', '{',
Bram Moolenaare828b762018-09-10 17:51:58 +0200981 \ ' int i;', ' for(i = 0; i < 10; i++)', ' {', ' printf("Your answer is: ");',
982 \ ' printf("%d\n", foo);', ' }', '}', '', 'int fact(int n)', '{', ' if(n > 1)', ' {',
983 \ ' return fact(n-1) * n;', ' }', ' return 1;', '}', '', 'int main(int argc, char **argv)',
984 \ '{', ' frobnitz(fact(10));', '}'],
985 \ ['#include <stdio.h>', '', 'int fib(int n)', '{', ' if(n > 2)', ' {',
986 \ ' return fib(n-1) + fib(n-2);', ' }', ' return 1;', '}', '', '// Frobs foo heartily',
987 \ 'int frobnitz(int foo)', '{', ' int i;', ' for(i = 0; i < 10; i++)', ' {',
988 \ ' printf("%d\n", foo);', ' }', '}', '',
989 \ 'int main(int argc, char **argv)', '{', ' frobnitz(fib(10));', '}'])
990 call term_sendkeys(buf, ":diffupdate!\<cr>")
991 call term_sendkeys(buf, ":set diffopt+=internal\<cr>")
992 call VerifyScreenDump(buf, 'Test_diff_07', {})
993
994 call term_sendkeys(buf, ":set diffopt+=algorithm:patience\<cr>")
995 call VerifyScreenDump(buf, 'Test_diff_08', {})
996
997 call term_sendkeys(buf, ":set diffopt+=algorithm:histogram\<cr>")
998 call VerifyScreenDump(buf, 'Test_diff_09', {})
999
1000 " Test 10-11: normal/indent-heuristic
1001 call term_sendkeys(buf, ":set diffopt&vim\<cr>")
Bram Moolenaar785fc652018-09-15 19:17:38 +02001002 call WriteDiffFiles(buf, ['', ' def finalize(values)', '', ' values.each do |v|', ' v.finalize', ' end'],
Bram Moolenaare828b762018-09-10 17:51:58 +02001003 \ ['', ' def finalize(values)', '', ' values.each do |v|', ' v.prepare', ' end', '',
1004 \ ' values.each do |v|', ' v.finalize', ' end'])
1005 call term_sendkeys(buf, ":diffupdate!\<cr>")
1006 call term_sendkeys(buf, ":set diffopt+=internal\<cr>")
1007 call VerifyScreenDump(buf, 'Test_diff_10', {})
1008
Bram Moolenaarb6fc7282018-12-04 22:24:16 +01001009 " Leave trailing : at commandline!
1010 call term_sendkeys(buf, ":set diffopt+=indent-heuristic\<cr>:\<cr>")
1011 call VerifyScreenDump(buf, 'Test_diff_11', {}, 'one')
1012 " shouldn't matter, if indent-algorithm comes before or after the algorithm
1013 call term_sendkeys(buf, ":set diffopt&\<cr>")
1014 call term_sendkeys(buf, ":set diffopt+=indent-heuristic,algorithm:patience\<cr>:\<cr>")
1015 call VerifyScreenDump(buf, 'Test_diff_11', {}, 'two')
1016 call term_sendkeys(buf, ":set diffopt&\<cr>")
1017 call term_sendkeys(buf, ":set diffopt+=algorithm:patience,indent-heuristic\<cr>:\<cr>")
1018 call VerifyScreenDump(buf, 'Test_diff_11', {}, 'three')
Bram Moolenaare828b762018-09-10 17:51:58 +02001019
1020 " Test 12: diff the same file
Bram Moolenaar785fc652018-09-15 19:17:38 +02001021 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 +02001022 call VerifyBoth(buf, 'Test_diff_12', '')
1023
1024 " Test 13: diff an empty file
Bram Moolenaar785fc652018-09-15 19:17:38 +02001025 call WriteDiffFiles(buf, [], [])
Bram Moolenaare828b762018-09-10 17:51:58 +02001026 call VerifyBoth(buf, 'Test_diff_13', '')
1027
1028 " Test 14: test diffopt+=icase
Bram Moolenaar785fc652018-09-15 19:17:38 +02001029 call WriteDiffFiles(buf, ['a', 'b', 'cd'], ['A', 'b', 'cDe'])
Bram Moolenaare828b762018-09-10 17:51:58 +02001030 call VerifyBoth(buf, 'Test_diff_14', " diffopt+=filler diffopt+=icase")
1031
1032 " Test 15-16: test diffopt+=iwhite
Bram Moolenaar785fc652018-09-15 19:17:38 +02001033 call WriteDiffFiles(buf, ['int main()', '{', ' printf("Hello, World!");', ' return 0;', '}'],
Bram Moolenaare828b762018-09-10 17:51:58 +02001034 \ ['int main()', '{', ' if (0)', ' {', ' printf("Hello, World!");', ' return 0;', ' }', '}'])
1035 call term_sendkeys(buf, ":diffupdate!\<cr>")
1036 call term_sendkeys(buf, ":set diffopt&vim diffopt+=filler diffopt+=iwhite\<cr>")
1037 call VerifyScreenDump(buf, 'Test_diff_15', {})
1038 call term_sendkeys(buf, ":set diffopt+=internal\<cr>")
1039 call VerifyScreenDump(buf, 'Test_diff_16', {})
1040
Bram Moolenaar785fc652018-09-15 19:17:38 +02001041 " Test 17: test diffopt+=iblank
1042 call WriteDiffFiles(buf, ['a', ' ', 'cd', 'ef', 'xxx'], ['a', 'cd', '', 'ef', 'yyy'])
1043 call VerifyInternal(buf, 'Test_diff_17', " diffopt+=iblank")
1044
1045 " Test 18: test diffopt+=iblank,iwhite / iwhiteall / iwhiteeol
1046 call VerifyInternal(buf, 'Test_diff_18', " diffopt+=iblank,iwhite")
1047 call VerifyInternal(buf, 'Test_diff_18', " diffopt+=iblank,iwhiteall")
1048 call VerifyInternal(buf, 'Test_diff_18', " diffopt+=iblank,iwhiteeol")
1049
1050 " Test 19: test diffopt+=iwhiteeol
1051 call WriteDiffFiles(buf, ['a ', 'x', 'cd', 'ef', 'xx xx', 'foo', 'bar'], ['a', 'x', 'c d', ' ef', 'xx xx', 'foo', '', 'bar'])
1052 call VerifyInternal(buf, 'Test_diff_19', " diffopt+=iwhiteeol")
1053
Yukihiro Nakadairaf1694b42024-09-22 11:26:13 +02001054 " Test 20: test diffopt+=iwhiteall
Bram Moolenaar785fc652018-09-15 19:17:38 +02001055 call VerifyInternal(buf, 'Test_diff_20', " diffopt+=iwhiteall")
1056
Yukihiro Nakadairaf1694b42024-09-22 11:26:13 +02001057 " Test 21: Delete all lines
1058 call WriteDiffFiles(buf, [0], [])
1059 call VerifyBoth(buf, "Test_diff_21", "")
1060
1061 " Test 22: Add line to empty file
1062 call WriteDiffFiles(buf, [], [0])
1063 call VerifyBoth(buf, "Test_diff_22", "")
1064
Jonathon7c7a4e62025-01-12 09:58:00 +01001065 call WriteDiffFiles(buf, ['?a', '?b', '?c'], ['!b'])
1066 call VerifyInternal(buf, 'Test_diff_23', " diffopt+=linematch:30")
1067
1068 call WriteDiffFiles(buf, ['',
1069 \ 'common line',
1070 \ 'common line',
1071 \ '',
1072 \ 'DEFabc',
1073 \ 'xyz',
1074 \ 'xyz',
1075 \ 'xyz',
1076 \ 'DEFabc',
1077 \ 'DEFabc',
1078 \ 'DEFabc',
1079 \ 'common line',
1080 \ 'common line',
1081 \ 'DEF',
1082 \ 'common line',
1083 \ 'DEF',
1084 \ 'something' ],
1085 \ ['',
1086 \ 'common line',
1087 \ 'common line',
1088 \ '',
1089 \ 'ABCabc',
1090 \ 'ABCabc',
1091 \ 'ABCabc',
1092 \ 'ABCabc',
1093 \ 'common line',
1094 \ 'common line',
1095 \ 'common line',
1096 \ 'something'])
1097 call VerifyInternal(buf, 'Test_diff_24', " diffopt+=linematch:30")
1098
1099
Bram Moolenaare828b762018-09-10 17:51:58 +02001100 " clean up
1101 call StopVimInTerminal(buf)
Bram Moolenaar61abe7d2022-08-30 21:46:08 +01001102 call delete('Xdifile1')
1103 call delete('Xdifile2')
Bram Moolenaare828b762018-09-10 17:51:58 +02001104endfunc
1105
Bram Moolenaar04626c22021-09-01 16:02:07 +02001106func Test_diff_with_scroll_and_change()
1107 CheckScreendump
1108
1109 let lines =<< trim END
1110 call setline(1, range(1, 15))
1111 vnew
1112 call setline(1, range(9, 15))
1113 windo diffthis
1114 wincmd h
1115 exe "normal Gl5\<C-E>"
1116 END
Bram Moolenaar59173412022-09-20 22:01:33 +01001117 call writefile(lines, 'Xtest_scroll_change', 'D')
Bram Moolenaar04626c22021-09-01 16:02:07 +02001118 let buf = RunVimInTerminal('-S Xtest_scroll_change', {})
1119
1120 call VerifyScreenDump(buf, 'Test_diff_scroll_change_01', {})
1121
1122 call term_sendkeys(buf, "ax\<Esc>")
1123 call VerifyScreenDump(buf, 'Test_diff_scroll_change_02', {})
1124
Bram Moolenaar841c2252021-10-22 20:56:55 +01001125 call term_sendkeys(buf, "\<C-W>lay\<Esc>")
1126 call VerifyScreenDump(buf, 'Test_diff_scroll_change_03', {})
1127
Bram Moolenaar04626c22021-09-01 16:02:07 +02001128 " clean up
1129 call StopVimInTerminal(buf)
Bram Moolenaar04626c22021-09-01 16:02:07 +02001130endfunc
1131
Bram Moolenaar4a5abbd2018-10-02 18:26:10 +02001132func Test_diff_with_cursorline()
Bram Moolenaar3c8ee622019-08-03 22:55:50 +02001133 CheckScreendump
Bram Moolenaar4a5abbd2018-10-02 18:26:10 +02001134
1135 call writefile([
1136 \ 'hi CursorLine ctermbg=red ctermfg=white',
1137 \ 'set cursorline',
1138 \ 'call setline(1, ["foo","foo","foo","bar"])',
1139 \ 'vnew',
1140 \ 'call setline(1, ["bee","foo","foo","baz"])',
1141 \ 'windo diffthis',
1142 \ '2wincmd w',
Bram Moolenaar59173412022-09-20 22:01:33 +01001143 \ ], 'Xtest_diff_cursorline', 'D')
Bram Moolenaar4a5abbd2018-10-02 18:26:10 +02001144 let buf = RunVimInTerminal('-S Xtest_diff_cursorline', {})
1145
1146 call VerifyScreenDump(buf, 'Test_diff_with_cursorline_01', {})
1147 call term_sendkeys(buf, "j")
1148 call VerifyScreenDump(buf, 'Test_diff_with_cursorline_02', {})
1149 call term_sendkeys(buf, "j")
1150 call VerifyScreenDump(buf, 'Test_diff_with_cursorline_03', {})
1151
1152 " clean up
1153 call StopVimInTerminal(buf)
Bram Moolenaar4a5abbd2018-10-02 18:26:10 +02001154endfunc
Bram Moolenaarf7acf2b2018-11-01 21:14:53 +01001155
Bram Moolenaar127969c2022-03-06 19:54:13 +00001156func Test_diff_with_cursorline_number()
1157 CheckScreendump
1158
1159 let lines =<< trim END
1160 hi CursorLine ctermbg=red ctermfg=white
1161 hi CursorLineNr ctermbg=white ctermfg=black cterm=underline
1162 set cursorline number
1163 call setline(1, ["baz", "foo", "foo", "bar"])
1164 2
1165 vnew
1166 call setline(1, ["foo", "foo", "bar"])
1167 windo diffthis
1168 1wincmd w
1169 END
Bram Moolenaar59173412022-09-20 22:01:33 +01001170 call writefile(lines, 'Xtest_diff_cursorline_number', 'D')
Bram Moolenaar127969c2022-03-06 19:54:13 +00001171 let buf = RunVimInTerminal('-S Xtest_diff_cursorline_number', {})
1172
1173 call VerifyScreenDump(buf, 'Test_diff_with_cursorline_number_01', {})
1174 call term_sendkeys(buf, ":set cursorlineopt=number\r")
1175 call VerifyScreenDump(buf, 'Test_diff_with_cursorline_number_02', {})
1176
1177 " clean up
1178 call StopVimInTerminal(buf)
Bram Moolenaar127969c2022-03-06 19:54:13 +00001179endfunc
1180
zeertzjq4f33bc22021-08-05 17:57:02 +02001181func Test_diff_with_cursorline_breakindent()
1182 CheckScreendump
1183
zeertzjq588f20d2023-12-05 15:47:09 +01001184 let lines =<< trim END
1185 hi CursorLine ctermbg=red ctermfg=white
1186 set noequalalways wrap diffopt=followwrap cursorline breakindent
1187 50vnew
1188 call setline(1, [' ', ' ', ' ', ' '])
1189 exe "norm! 20Afoo\<Esc>j20Afoo\<Esc>j20Afoo\<Esc>j20Abar\<Esc>"
1190 vnew
1191 call setline(1, [' ', ' ', ' ', ' '])
1192 exe "norm! 20Abee\<Esc>j20Afoo\<Esc>j20Afoo\<Esc>j20Abaz\<Esc>"
1193 windo diffthis
1194 2wincmd w
1195 END
1196 call writefile(lines, 'Xtest_diff_cursorline_breakindent', 'D')
zeertzjq4f33bc22021-08-05 17:57:02 +02001197 let buf = RunVimInTerminal('-S Xtest_diff_cursorline_breakindent', {})
1198
1199 call term_sendkeys(buf, "gg0")
1200 call VerifyScreenDump(buf, 'Test_diff_with_cul_bri_01', {})
1201 call term_sendkeys(buf, "j")
1202 call VerifyScreenDump(buf, 'Test_diff_with_cul_bri_02', {})
1203 call term_sendkeys(buf, "j")
1204 call VerifyScreenDump(buf, 'Test_diff_with_cul_bri_03', {})
1205 call term_sendkeys(buf, "j")
1206 call VerifyScreenDump(buf, 'Test_diff_with_cul_bri_04', {})
1207
1208 " clean up
1209 call StopVimInTerminal(buf)
zeertzjq4f33bc22021-08-05 17:57:02 +02001210endfunc
1211
zeertzjq588f20d2023-12-05 15:47:09 +01001212func Test_diff_breakindent_after_filler()
1213 CheckScreendump
1214
1215 let lines =<< trim END
zeertzjqf0a9d652024-02-12 22:53:20 +01001216 set laststatus=0 diffopt+=followwrap breakindent breakindentopt=min:0
zeertzjq588f20d2023-12-05 15:47:09 +01001217 call setline(1, ['a', ' ' .. repeat('c', 50)])
1218 vnew
1219 call setline(1, ['a', 'b', ' ' .. repeat('c', 50)])
1220 windo diffthis
1221 norm! G$
1222 END
1223 call writefile(lines, 'Xtest_diff_breakindent_after_filler', 'D')
1224 let buf = RunVimInTerminal('-S Xtest_diff_breakindent_after_filler', #{rows: 8, cols: 45})
1225 call VerifyScreenDump(buf, 'Test_diff_breakindent_after_filler', {})
1226
1227 " clean up
1228 call StopVimInTerminal(buf)
1229endfunc
1230
Bram Moolenaar248fdb32019-09-15 19:31:28 +02001231func Test_diff_with_syntax()
1232 CheckScreendump
1233
1234 let lines =<< trim END
Bram Moolenaar94722c52023-01-28 19:19:03 +00001235 void doNothing() {
Bram Moolenaar248fdb32019-09-15 19:31:28 +02001236 int x = 0;
1237 char *s = "hello";
1238 return 5;
1239 }
1240 END
Bram Moolenaar59173412022-09-20 22:01:33 +01001241 call writefile(lines, 'Xprogram1.c', 'D')
Bram Moolenaar248fdb32019-09-15 19:31:28 +02001242 let lines =<< trim END
Bram Moolenaar94722c52023-01-28 19:19:03 +00001243 void doSomething() {
Bram Moolenaar248fdb32019-09-15 19:31:28 +02001244 int x = 0;
1245 char *s = "there";
1246 return 5;
1247 }
1248 END
Bram Moolenaar59173412022-09-20 22:01:33 +01001249 call writefile(lines, 'Xprogram2.c', 'D')
Bram Moolenaar248fdb32019-09-15 19:31:28 +02001250
1251 let lines =<< trim END
Bram Moolenaar94722c52023-01-28 19:19:03 +00001252 edit Xprogram1.c
Bram Moolenaar248fdb32019-09-15 19:31:28 +02001253 diffsplit Xprogram2.c
1254 END
Bram Moolenaar59173412022-09-20 22:01:33 +01001255 call writefile(lines, 'Xtest_diff_syntax', 'D')
Bram Moolenaar248fdb32019-09-15 19:31:28 +02001256 let buf = RunVimInTerminal('-S Xtest_diff_syntax', {})
1257
1258 call VerifyScreenDump(buf, 'Test_diff_syntax_1', {})
1259
1260 " clean up
1261 call StopVimInTerminal(buf)
Bram Moolenaar248fdb32019-09-15 19:31:28 +02001262endfunc
1263
Bram Moolenaarf7acf2b2018-11-01 21:14:53 +01001264func Test_diff_of_diff()
Bram Moolenaar3c8ee622019-08-03 22:55:50 +02001265 CheckScreendump
1266 CheckFeature rightleft
Bram Moolenaarf7acf2b2018-11-01 21:14:53 +01001267
1268 call writefile([
1269 \ 'call setline(1, ["aa","bb","cc","@@ -3,2 +5,7 @@","dd","ee","ff"])',
1270 \ 'vnew',
1271 \ 'call setline(1, ["aa","bb","cc"])',
1272 \ 'windo diffthis',
Bram Moolenaar8ee4c012019-03-29 18:08:18 +01001273 \ '1wincmd w',
1274 \ 'setlocal number',
Bram Moolenaar59173412022-09-20 22:01:33 +01001275 \ ], 'Xtest_diff_diff', 'D')
Bram Moolenaarf7acf2b2018-11-01 21:14:53 +01001276 let buf = RunVimInTerminal('-S Xtest_diff_diff', {})
1277
1278 call VerifyScreenDump(buf, 'Test_diff_of_diff_01', {})
1279
Bram Moolenaare73f9112019-03-29 18:29:54 +01001280 call term_sendkeys(buf, ":set rightleft\<cr>")
1281 call VerifyScreenDump(buf, 'Test_diff_of_diff_02', {})
1282
Bram Moolenaarf7acf2b2018-11-01 21:14:53 +01001283 " clean up
1284 call StopVimInTerminal(buf)
Bram Moolenaarf7acf2b2018-11-01 21:14:53 +01001285endfunc
Bram Moolenaarc8234772019-11-10 21:00:27 +01001286
1287func CloseoffSetup()
1288 enew
1289 call setline(1, ['one', 'two', 'three'])
1290 diffthis
1291 new
1292 call setline(1, ['one', 'tow', 'three'])
1293 diffthis
1294 call assert_equal(1, &diff)
Jonathonca307ef2025-01-17 13:37:35 +01001295 bw!
Bram Moolenaarc8234772019-11-10 21:00:27 +01001296endfunc
1297
1298func Test_diff_closeoff()
1299 " "closeoff" included by default: last diff win gets 'diff' reset'
1300 call CloseoffSetup()
1301 call assert_equal(0, &diff)
1302 enew!
1303
1304 " "closeoff" excluded: last diff win keeps 'diff' set'
1305 set diffopt-=closeoff
1306 call CloseoffSetup()
1307 call assert_equal(1, &diff)
1308 diffoff!
1309 enew!
1310endfunc
Bram Moolenaarf4a1d1c2019-11-16 13:50:25 +01001311
Bram Moolenaar4223d432021-02-10 13:18:17 +01001312func Test_diff_followwrap()
1313 new
1314 set diffopt+=followwrap
1315 set wrap
1316 diffthis
1317 call assert_equal(1, &wrap)
1318 diffoff
1319 set nowrap
1320 diffthis
1321 call assert_equal(0, &wrap)
1322 diffoff
1323 set diffopt&
1324 bwipe!
1325endfunc
1326
Bram Moolenaarf4a1d1c2019-11-16 13:50:25 +01001327func Test_diff_maintains_change_mark()
Sean Dewarccc16442021-12-29 16:44:48 +00001328 func DiffMaintainsChangeMark()
1329 enew!
1330 call setline(1, ['a', 'b', 'c', 'd'])
1331 diffthis
1332 new
1333 call setline(1, ['a', 'b', 'c', 'e'])
1334 " Set '[ and '] marks
1335 2,3yank
1336 call assert_equal([2, 3], [line("'["), line("']")])
1337 " Verify they aren't affected by the implicit diff
1338 diffthis
1339 call assert_equal([2, 3], [line("'["), line("']")])
1340 " Verify they aren't affected by an explicit diff
1341 diffupdate
1342 call assert_equal([2, 3], [line("'["), line("']")])
1343 bwipe!
1344 bwipe!
1345 endfunc
1346
1347 set diffopt-=internal
1348 call DiffMaintainsChangeMark()
1349 set diffopt+=internal
1350 call DiffMaintainsChangeMark()
Bram Moolenaard9b74a22022-01-16 15:00:08 +00001351
Sean Dewarccc16442021-12-29 16:44:48 +00001352 set diffopt&
Bram Moolenaard9b74a22022-01-16 15:00:08 +00001353 delfunc DiffMaintainsChangeMark
Bram Moolenaarf4a1d1c2019-11-16 13:50:25 +01001354endfunc
Bram Moolenaar8dfcce32020-03-18 19:32:26 +01001355
1356" Test for 'patchexpr'
1357func Test_patchexpr()
1358 let g:patch_args = []
1359 func TPatch()
1360 call add(g:patch_args, readfile(v:fname_in))
1361 call add(g:patch_args, readfile(v:fname_diff))
1362 call writefile(['output file'], v:fname_out)
1363 endfunc
1364 set patchexpr=TPatch()
1365
Bram Moolenaar59173412022-09-20 22:01:33 +01001366 call writefile(['input file'], 'Xinput', 'D')
1367 call writefile(['diff file'], 'Xdiff', 'D')
Bram Moolenaar8dfcce32020-03-18 19:32:26 +01001368 %bwipe!
1369 edit Xinput
1370 diffpatch Xdiff
1371 call assert_equal('output file', getline(1))
1372 call assert_equal('Xinput.new', bufname())
1373 call assert_equal(2, winnr('$'))
1374 call assert_true(&diff)
1375
Yegappan Lakshmanan8bb65f22021-12-26 10:51:39 +00001376 " Using a script-local function
1377 func s:NewPatchExpr()
1378 endfunc
1379 set patchexpr=s:NewPatchExpr()
1380 call assert_equal(expand('<SID>') .. 'NewPatchExpr()', &patchexpr)
1381 set patchexpr=<SID>NewPatchExpr()
1382 call assert_equal(expand('<SID>') .. 'NewPatchExpr()', &patchexpr)
1383
Bram Moolenaar8dfcce32020-03-18 19:32:26 +01001384 set patchexpr&
1385 delfunc TPatch
Yegappan Lakshmanan8bb65f22021-12-26 10:51:39 +00001386 delfunc s:NewPatchExpr
Bram Moolenaar8dfcce32020-03-18 19:32:26 +01001387 %bwipe!
1388endfunc
1389
Bram Moolenaar511feec2020-06-18 19:15:27 +02001390func Test_diff_rnu()
1391 CheckScreendump
1392
1393 let content =<< trim END
1394 call setline(1, ['a', 'a', 'a', 'y', 'b', 'b', 'b', 'b', 'b'])
1395 vnew
1396 call setline(1, ['a', 'a', 'a', 'x', 'x', 'x', 'b', 'b', 'b', 'b', 'b'])
1397 windo diffthis
1398 setlocal number rnu foldcolumn=0
1399 END
Bram Moolenaar59173412022-09-20 22:01:33 +01001400 call writefile(content, 'Xtest_diff_rnu', 'D')
Bram Moolenaar511feec2020-06-18 19:15:27 +02001401 let buf = RunVimInTerminal('-S Xtest_diff_rnu', {})
1402
1403 call VerifyScreenDump(buf, 'Test_diff_rnu_01', {})
1404
1405 call term_sendkeys(buf, "j")
1406 call VerifyScreenDump(buf, 'Test_diff_rnu_02', {})
1407 call term_sendkeys(buf, "j")
1408 call VerifyScreenDump(buf, 'Test_diff_rnu_03', {})
1409
1410 " clean up
1411 call StopVimInTerminal(buf)
Bram Moolenaar511feec2020-06-18 19:15:27 +02001412endfunc
1413
Bram Moolenaarfc838d62020-06-25 22:23:48 +02001414func Test_diff_multilineconceal()
1415 new
1416 diffthis
1417
1418 new
1419 call matchadd('Conceal', 'a\nb', 9, -1, {'conceal': 'Y'})
1420 set cole=2 cocu=n
1421 call setline(1, ["a", "b"])
1422 diffthis
1423 redraw
1424endfunc
1425
Bram Moolenaar8455c5e2020-07-14 21:22:30 +02001426func Test_diff_and_scroll()
1427 " this was causing an ml_get error
1428 set ls=2
Bram Moolenaar94722c52023-01-28 19:19:03 +00001429 for i in range(winheight(0) * 2)
1430 call setline(i, i < winheight(0) - 10 ? i : i + 10)
Bram Moolenaar8455c5e2020-07-14 21:22:30 +02001431 endfor
1432 vnew
Bram Moolenaar94722c52023-01-28 19:19:03 +00001433 for i in range(winheight(0)*2 + 10)
1434 call setline(i, i < winheight(0) - 10 ? 0 : i)
Bram Moolenaar8455c5e2020-07-14 21:22:30 +02001435 endfor
1436 diffthis
1437 wincmd p
1438 diffthis
1439 execute 'normal ' . winheight(0) . "\<C-d>"
1440
1441 bwipe!
1442 bwipe!
1443 set ls&
1444endfunc
1445
Bram Moolenaarfabc3ca2020-11-05 19:07:21 +01001446func Test_diff_filler_cursorcolumn()
1447 CheckScreendump
1448
1449 let content =<< trim END
1450 call setline(1, ['aa', 'bb', 'cc'])
1451 vnew
1452 call setline(1, ['aa', 'cc'])
1453 windo diffthis
1454 wincmd p
1455 setlocal cursorcolumn foldcolumn=0
1456 norm! gg0
1457 redraw!
1458 END
Bram Moolenaar59173412022-09-20 22:01:33 +01001459 call writefile(content, 'Xtest_diff_cuc', 'D')
Bram Moolenaarfabc3ca2020-11-05 19:07:21 +01001460 let buf = RunVimInTerminal('-S Xtest_diff_cuc', {})
1461
1462 call VerifyScreenDump(buf, 'Test_diff_cuc_01', {})
1463
1464 call term_sendkeys(buf, "l")
1465 call term_sendkeys(buf, "\<C-l>")
1466 call VerifyScreenDump(buf, 'Test_diff_cuc_02', {})
1467 call term_sendkeys(buf, "0j")
1468 call term_sendkeys(buf, "\<C-l>")
1469 call VerifyScreenDump(buf, 'Test_diff_cuc_03', {})
1470 call term_sendkeys(buf, "l")
1471 call term_sendkeys(buf, "\<C-l>")
1472 call VerifyScreenDump(buf, 'Test_diff_cuc_04', {})
1473
1474 " clean up
1475 call StopVimInTerminal(buf)
Bram Moolenaarfabc3ca2020-11-05 19:07:21 +01001476endfunc
1477
Yegappan Lakshmanan30443242021-06-10 21:52:15 +02001478" Test for adding/removing lines inside diff chunks, between diff chunks
1479" and before diff chunks
1480func Test_diff_modify_chunks()
1481 enew!
1482 let w2_id = win_getid()
1483 call setline(1, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'])
1484 new
1485 let w1_id = win_getid()
1486 call setline(1, ['a', '2', '3', 'd', 'e', 'f', '7', '8', 'i'])
1487 windo diffthis
1488
1489 " remove a line between two diff chunks and create a new diff chunk
1490 call win_gotoid(w2_id)
1491 5d
1492 call win_gotoid(w1_id)
1493 call diff_hlID(5, 1)->synIDattr('name')->assert_equal('DiffAdd')
1494
1495 " add a line between two diff chunks
1496 call win_gotoid(w2_id)
1497 normal! 4Goe
1498 call win_gotoid(w1_id)
1499 call diff_hlID(4, 1)->synIDattr('name')->assert_equal('')
1500 call diff_hlID(5, 1)->synIDattr('name')->assert_equal('')
1501
1502 " remove all the lines in a diff chunk.
1503 call win_gotoid(w2_id)
1504 7,8d
1505 call win_gotoid(w1_id)
1506 let hl = range(1, 9)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')})
1507 call assert_equal(['', 'DiffText', 'DiffText', '', '', '', 'DiffAdd',
1508 \ 'DiffAdd', ''], hl)
1509
1510 " remove lines from one diff chunk to just before the next diff chunk
1511 call win_gotoid(w2_id)
1512 call setline(1, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'])
1513 2,6d
1514 call win_gotoid(w1_id)
1515 let hl = range(1, 9)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')})
1516 call assert_equal(['', 'DiffText', 'DiffText', 'DiffAdd', 'DiffAdd',
1517 \ 'DiffAdd', 'DiffAdd', 'DiffAdd', ''], hl)
1518
1519 " remove lines just before the top of a diff chunk
1520 call win_gotoid(w2_id)
1521 call setline(1, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'])
1522 5,6d
1523 call win_gotoid(w1_id)
1524 let hl = range(1, 9)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')})
1525 call assert_equal(['', 'DiffText', 'DiffText', '', 'DiffText', 'DiffText',
1526 \ 'DiffAdd', 'DiffAdd', ''], hl)
1527
1528 " remove line after the end of a diff chunk
1529 call win_gotoid(w2_id)
1530 call setline(1, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'])
1531 4d
1532 call win_gotoid(w1_id)
1533 let hl = range(1, 9)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')})
1534 call assert_equal(['', 'DiffText', 'DiffText', 'DiffAdd', '', '', 'DiffText',
1535 \ 'DiffText', ''], hl)
1536
1537 " remove lines starting from the end of one diff chunk and ending inside
1538 " another diff chunk
1539 call win_gotoid(w2_id)
1540 call setline(1, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'])
1541 4,7d
1542 call win_gotoid(w1_id)
1543 let hl = range(1, 9)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')})
1544 call assert_equal(['', 'DiffText', 'DiffText', 'DiffText', 'DiffAdd',
1545 \ 'DiffAdd', 'DiffAdd', 'DiffAdd', ''], hl)
1546
1547 " removing the only remaining diff chunk should make the files equal
1548 call win_gotoid(w2_id)
1549 call setline(1, ['a', '2', '3', 'x', 'd', 'e', 'f', 'x', '7', '8', 'i'])
1550 8d
1551 let hl = range(1, 10)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')})
1552 call assert_equal(['', '', '', 'DiffAdd', '', '', '', '', '', ''], hl)
1553 call win_gotoid(w2_id)
1554 4d
1555 call win_gotoid(w1_id)
1556 let hl = range(1, 9)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')})
1557 call assert_equal(['', '', '', '', '', '', '', '', ''], hl)
1558
1559 %bw!
1560endfunc
glacambread5c1782021-05-24 14:20:53 +02001561
Bram Moolenaar06f60952021-12-28 18:30:05 +00001562func Test_diff_binary()
1563 CheckScreendump
1564
1565 let content =<< trim END
1566 call setline(1, ['a', 'b', "c\n", 'd', 'e', 'f', 'g'])
1567 vnew
1568 call setline(1, ['A', 'b', 'c', 'd', 'E', 'f', 'g'])
1569 windo diffthis
1570 wincmd p
1571 norm! gg0
1572 redraw!
1573 END
Bram Moolenaar59173412022-09-20 22:01:33 +01001574 call writefile(content, 'Xtest_diff_bin', 'D')
Bram Moolenaar06f60952021-12-28 18:30:05 +00001575 let buf = RunVimInTerminal('-S Xtest_diff_bin', {})
1576
1577 " Test using internal diff
1578 call VerifyScreenDump(buf, 'Test_diff_bin_01', {})
1579
1580 " Test using internal diff and case folding
1581 call term_sendkeys(buf, ":set diffopt+=icase\<cr>")
1582 call term_sendkeys(buf, "\<C-l>")
1583 call VerifyScreenDump(buf, 'Test_diff_bin_02', {})
1584 " Test using external diff
1585 call term_sendkeys(buf, ":set diffopt=filler\<cr>")
1586 call term_sendkeys(buf, "\<C-l>")
1587 call VerifyScreenDump(buf, 'Test_diff_bin_03', {})
1588 " Test using external diff and case folding
1589 call term_sendkeys(buf, ":set diffopt=filler,icase\<cr>")
1590 call term_sendkeys(buf, "\<C-l>")
1591 call VerifyScreenDump(buf, 'Test_diff_bin_04', {})
1592
1593 " clean up
1594 call StopVimInTerminal(buf)
Bram Moolenaar06f60952021-12-28 18:30:05 +00001595 set diffopt&vim
1596endfunc
1597
Yegappan Lakshmananb0ad2d92022-01-27 13:16:59 +00001598" Test for using the 'zi' command to invert 'foldenable' in diff windows (test
1599" for the issue fixed by patch 6.2.317)
1600func Test_diff_foldinvert()
1601 %bw!
Bram Moolenaar61abe7d2022-08-30 21:46:08 +01001602 edit Xdoffile1
1603 new Xdoffile2
1604 new Xdoffile3
Yegappan Lakshmananb0ad2d92022-01-27 13:16:59 +00001605 windo diffthis
1606 " open a non-diff window
1607 botright new
1608 1wincmd w
1609 call assert_true(getwinvar(1, '&foldenable'))
1610 call assert_true(getwinvar(2, '&foldenable'))
1611 call assert_true(getwinvar(3, '&foldenable'))
1612 normal zi
1613 call assert_false(getwinvar(1, '&foldenable'))
1614 call assert_false(getwinvar(2, '&foldenable'))
1615 call assert_false(getwinvar(3, '&foldenable'))
1616 normal zi
1617 call assert_true(getwinvar(1, '&foldenable'))
1618 call assert_true(getwinvar(2, '&foldenable'))
1619 call assert_true(getwinvar(3, '&foldenable'))
1620
1621 " If the current window has 'noscrollbind', then 'zi' should not change
1622 " 'foldenable' in other windows.
1623 1wincmd w
1624 set noscrollbind
1625 normal zi
1626 call assert_false(getwinvar(1, '&foldenable'))
1627 call assert_true(getwinvar(2, '&foldenable'))
1628 call assert_true(getwinvar(3, '&foldenable'))
1629
1630 " 'zi' should not change the 'foldenable' for windows with 'noscrollbind'
1631 1wincmd w
1632 set scrollbind
1633 normal zi
1634 call setwinvar(2, '&scrollbind', v:false)
1635 normal zi
1636 call assert_false(getwinvar(1, '&foldenable'))
1637 call assert_true(getwinvar(2, '&foldenable'))
1638 call assert_false(getwinvar(3, '&foldenable'))
1639
1640 %bw!
1641 set scrollbind&
1642endfunc
1643
Bram Moolenaara315ce12022-06-24 12:38:57 +01001644" This was scrolling for 'cursorbind' but 'scrollbind' is more important
1645func Test_diff_scroll()
1646 CheckScreendump
1647
1648 let left =<< trim END
1649 line 1
1650 line 2
1651 line 3
1652 line 4
1653
1654 // Common block
1655 // one
1656 // containing
1657 // four lines
1658
1659 // Common block
1660 // two
1661 // containing
1662 // four lines
1663 END
Bram Moolenaar59173412022-09-20 22:01:33 +01001664 call writefile(left, 'Xleft', 'D')
Bram Moolenaara315ce12022-06-24 12:38:57 +01001665 let right =<< trim END
1666 line 1
1667 line 2
1668 line 3
1669 line 4
1670
1671 Lorem
1672 ipsum
1673 dolor
1674 sit
1675 amet,
1676 consectetur
1677 adipiscing
1678 elit.
1679 Etiam
1680 luctus
1681 lectus
1682 sodales,
1683 dictum
1684
1685 // Common block
1686 // one
1687 // containing
1688 // four lines
1689
1690 Vestibulum
1691 tincidunt
1692 aliquet
1693 nulla.
1694
1695 // Common block
1696 // two
1697 // containing
1698 // four lines
1699 END
Bram Moolenaar59173412022-09-20 22:01:33 +01001700 call writefile(right, 'Xright', 'D')
Bram Moolenaara315ce12022-06-24 12:38:57 +01001701 let buf = RunVimInTerminal('-d Xleft Xright', {'rows': 12})
1702 call term_sendkeys(buf, "\<C-W>\<C-W>jjjj")
1703 call VerifyScreenDump(buf, 'Test_diff_scroll_1', {})
1704 call term_sendkeys(buf, "j")
1705 call VerifyScreenDump(buf, 'Test_diff_scroll_2', {})
1706
1707 call StopVimInTerminal(buf)
Bram Moolenaara315ce12022-06-24 12:38:57 +01001708endfunc
1709
Bram Moolenaar38d867f2023-04-01 19:54:40 +01001710" This was scrolling too many lines.
1711func Test_diff_scroll_wrap_on()
1712 20new
1713 40vsplit
1714 call setline(1, map(range(1, 9), 'repeat(v:val, 200)'))
1715 setlocal number diff so=0
1716 redraw
1717 normal! jj
1718 call assert_equal(1, winsaveview().topline)
1719 normal! j
1720 call assert_equal(2, winsaveview().topline)
zeertzjq05834912023-10-04 20:12:37 +02001721
1722 bwipe!
1723 bwipe!
1724endfunc
1725
1726func Test_diff_scroll_many_filler()
1727 20new
1728 vnew
Luuk van Baalb9f5b952024-03-26 18:46:45 +01001729 call setline(1, range(1, 40))
zeertzjq05834912023-10-04 20:12:37 +02001730 diffthis
1731 setlocal scrolloff=0
1732 wincmd p
Luuk van Baalb9f5b952024-03-26 18:46:45 +01001733 call setline(1, range(1, 20)->reverse() + ['###']->repeat(41) + range(21, 40)->reverse())
zeertzjq05834912023-10-04 20:12:37 +02001734 diffthis
1735 setlocal scrolloff=0
1736 wincmd p
1737 redraw
1738
1739 " Note: need a redraw after each scroll, otherwise the test always passes.
Luuk van Baalb9f5b952024-03-26 18:46:45 +01001740 for _ in range(2)
1741 normal! G
1742 redraw
1743 call assert_equal(40, winsaveview().topline)
1744 call assert_equal(19, winsaveview().topfill)
1745 exe "normal! \<C-B>"
1746 redraw
1747 call assert_equal(22, winsaveview().topline)
1748 call assert_equal(0, winsaveview().topfill)
1749 exe "normal! \<C-B>"
1750 redraw
1751 call assert_equal(4, winsaveview().topline)
1752 call assert_equal(0, winsaveview().topfill)
1753 exe "normal! \<C-B>"
1754 redraw
1755 call assert_equal(1, winsaveview().topline)
1756 call assert_equal(0, winsaveview().topfill)
1757 set smoothscroll
1758 endfor
zeertzjq05834912023-10-04 20:12:37 +02001759
Luuk van Baalb9f5b952024-03-26 18:46:45 +01001760 set smoothscroll&
Luuk van Baalcb204e62024-04-02 20:49:45 +02001761 %bwipe!
Bram Moolenaar38d867f2023-04-01 19:54:40 +01001762endfunc
1763
Bram Moolenaarcd38bb42022-06-26 14:04:07 +01001764" This was trying to update diffs for a buffer being closed
1765func Test_diff_only()
1766 silent! lfile
1767 set diff
1768 lopen
1769 norm o
1770 silent! norm o
1771
1772 set nodiff
1773 %bwipe!
1774endfunc
1775
Bram Moolenaarc101abf2022-06-26 16:53:34 +01001776" This was causing invalid diff block values
1777" FIXME: somehow this causes a valgrind error when run directly but not when
1778" run as a test.
1779func Test_diff_manipulations()
1780 set diff
1781 split 0
1782 sil! norm R doobdeuR doobdeuR doobdeu
1783
1784 set nodiff
1785 %bwipe!
1786endfunc
1787
Bram Moolenaar4e677b92022-07-28 18:44:27 +01001788" This was causing the line number in the diff block to go below one.
1789" FIXME: somehow this causes a valgrind error when run directly but not when
1790" run as a test.
1791func Test_diff_put_and_undo()
1792 set diff
1793 next 0
1794 split 00
1795 sil! norm o0gguudpo0ggJuudp
1796
1797 bwipe!
1798 bwipe!
1799 set nodiff
1800endfunc
1801
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001802" Test for the diff() function
1803def Test_diff_func()
1804 # string is added/removed/modified at the beginning
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001805 assert_equal("@@ -0,0 +1 @@\n+abc\n",
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001806 diff(['def'], ['abc', 'def'], {output: 'unified'}))
1807 assert_equal([{from_idx: 0, from_count: 0, to_idx: 0, to_count: 1}],
1808 diff(['def'], ['abc', 'def'], {output: 'indices'}))
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001809 assert_equal("@@ -1 +0,0 @@\n-abc\n",
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001810 diff(['abc', 'def'], ['def'], {output: 'unified'}))
1811 assert_equal([{from_idx: 0, from_count: 1, to_idx: 0, to_count: 0}],
1812 diff(['abc', 'def'], ['def'], {output: 'indices'}))
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001813 assert_equal("@@ -1 +1 @@\n-abc\n+abx\n",
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001814 diff(['abc', 'def'], ['abx', 'def'], {output: 'unified'}))
1815 assert_equal([{from_idx: 0, from_count: 1, to_idx: 0, to_count: 1}],
1816 diff(['abc', 'def'], ['abx', 'def'], {output: 'indices'}))
1817
1818 # string is added/removed/modified at the end
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001819 assert_equal("@@ -1,0 +2 @@\n+def\n",
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001820 diff(['abc'], ['abc', 'def'], {output: 'unified'}))
1821 assert_equal([{from_idx: 1, from_count: 0, to_idx: 1, to_count: 1}],
1822 diff(['abc'], ['abc', 'def'], {output: 'indices'}))
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001823 assert_equal("@@ -2 +1,0 @@\n-def\n",
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001824 diff(['abc', 'def'], ['abc'], {output: 'unified'}))
1825 assert_equal([{from_idx: 1, from_count: 1, to_idx: 1, to_count: 0}],
1826 diff(['abc', 'def'], ['abc'], {output: 'indices'}))
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001827 assert_equal("@@ -2 +2 @@\n-def\n+xef\n",
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001828 diff(['abc', 'def'], ['abc', 'xef'], {output: 'unified'}))
1829 assert_equal([{from_idx: 1, from_count: 1, to_idx: 1, to_count: 1}],
1830 diff(['abc', 'def'], ['abc', 'xef'], {output: 'indices'}))
1831
1832 # string is added/removed/modified in the middle
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001833 assert_equal("@@ -2,0 +3 @@\n+xxx\n",
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001834 diff(['111', '222', '333'], ['111', '222', 'xxx', '333'], {output: 'unified'}))
1835 assert_equal([{from_idx: 2, from_count: 0, to_idx: 2, to_count: 1}],
1836 diff(['111', '222', '333'], ['111', '222', 'xxx', '333'], {output: 'indices'}))
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001837 assert_equal("@@ -3 +2,0 @@\n-333\n",
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001838 diff(['111', '222', '333', '444'], ['111', '222', '444'], {output: 'unified'}))
1839 assert_equal([{from_idx: 2, from_count: 1, to_idx: 2, to_count: 0}],
1840 diff(['111', '222', '333', '444'], ['111', '222', '444'], {output: 'indices'}))
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001841 assert_equal("@@ -3 +3 @@\n-333\n+xxx\n",
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001842 diff(['111', '222', '333', '444'], ['111', '222', 'xxx', '444'], {output: 'unified'}))
1843 assert_equal([{from_idx: 2, from_count: 1, to_idx: 2, to_count: 1}],
1844 diff(['111', '222', '333', '444'], ['111', '222', 'xxx', '444'], {output: 'indices'}))
1845
1846 # new strings are added to an empty List
1847 assert_equal("@@ -0,0 +1,2 @@\n+abc\n+def\n",
1848 diff([], ['abc', 'def'], {output: 'unified'}))
1849 assert_equal([{from_idx: 0, from_count: 0, to_idx: 0, to_count: 2}],
1850 diff([], ['abc', 'def'], {output: 'indices'}))
1851
1852 # all the strings are removed from a List
1853 assert_equal("@@ -1,2 +0,0 @@\n-abc\n-def\n",
1854 diff(['abc', 'def'], [], {output: 'unified'}))
1855 assert_equal([{from_idx: 0, from_count: 2, to_idx: 0, to_count: 0}],
1856 diff(['abc', 'def'], [], {output: 'indices'}))
1857
1858 # First character is added/removed/different
1859 assert_equal("@@ -1 +1 @@\n-abc\n+bc\n",
1860 diff(['abc'], ['bc'], {output: 'unified'}))
1861 assert_equal([{from_idx: 0, from_count: 1, to_idx: 0, to_count: 1}],
1862 diff(['abc'], ['bc'], {output: 'indices'}))
1863 assert_equal("@@ -1 +1 @@\n-bc\n+abc\n",
1864 diff(['bc'], ['abc'], {output: 'unified'}))
1865 assert_equal([{from_idx: 0, from_count: 1, to_idx: 0, to_count: 1}],
1866 diff(['bc'], ['abc'], {output: 'indices'}))
1867 assert_equal("@@ -1 +1 @@\n-abc\n+xbc\n",
1868 diff(['abc'], ['xbc'], {output: 'unified'}))
1869 assert_equal([{from_idx: 0, from_count: 1, to_idx: 0, to_count: 1}],
1870 diff(['abc'], ['xbc'], {output: 'indices'}))
1871
1872 # Last character is added/removed/different
1873 assert_equal("@@ -1 +1 @@\n-abc\n+abcd\n",
1874 diff(['abc'], ['abcd'], {output: 'unified'}))
1875 assert_equal([{from_idx: 0, from_count: 1, to_idx: 0, to_count: 1}],
1876 diff(['abc'], ['abcd'], {output: 'indices'}))
1877 assert_equal("@@ -1 +1 @@\n-abcd\n+abc\n",
1878 diff(['abcd'], ['abc'], {output: 'unified'}))
1879 assert_equal([{from_idx: 0, from_count: 1, to_idx: 0, to_count: 1}],
1880 diff(['abcd'], ['abc'], {output: 'indices'}))
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001881 var diff_unified: string = diff(['abc'], ['abx'], {output: 'unified'})
1882 assert_equal("@@ -1 +1 @@\n-abc\n+abx\n", diff_unified)
1883 var diff_indices: list<dict<number>> =
1884 diff(['abc'], ['abx'], {output: 'indices'})
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001885 assert_equal([{from_idx: 0, from_count: 1, to_idx: 0, to_count: 1}],
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001886 diff_indices)
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001887
1888 # partial string modification at the start and at the end.
1889 var fromlist =<< trim END
1890 one two
1891 three four
1892 five six
1893 END
1894 var tolist =<< trim END
1895 one
1896 six
1897 END
1898 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'}))
1899 assert_equal([{from_idx: 0, from_count: 3, to_idx: 0, to_count: 2}],
1900 diff(fromlist, tolist, {output: 'indices'}))
1901
1902 # non-contiguous modifications
1903 fromlist =<< trim END
1904 one two
1905 three four
1906 five abc six
1907 END
1908 tolist =<< trim END
1909 one abc two
1910 three four
1911 five six
1912 END
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001913 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 +01001914 diff(fromlist, tolist, {output: 'unified'}))
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001915 assert_equal([{'from_count': 1, 'to_idx': 0, 'to_count': 1, 'from_idx': 0},
1916 {'from_count': 1, 'to_idx': 2, 'to_count': 1, 'from_idx': 2}],
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001917 diff(fromlist, tolist, {output: 'indices'}))
1918
1919 # add/remove blank lines
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001920 assert_equal("@@ -2,2 +1,0 @@\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: 2, to_idx: 1, to_count: 0}],
1923 diff(['one', '', '', 'two'], ['one', 'two'], {output: 'indices'}))
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01001924 assert_equal("@@ -1,0 +2,2 @@\n+\n+\n",
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01001925 diff(['one', 'two'], ['one', '', '', 'two'], {output: 'unified'}))
1926 assert_equal([{'from_idx': 1, 'from_count': 0, 'to_idx': 1, 'to_count': 2}],
1927 diff(['one', 'two'], ['one', '', '', 'two'], {output: 'indices'}))
1928
1929 # diff ignoring case
1930 assert_equal('', diff(['abc', 'def'], ['ABC', 'DEF'], {icase: true, output: 'unified'}))
1931 assert_equal([], diff(['abc', 'def'], ['ABC', 'DEF'], {icase: true, output: 'indices'}))
1932
1933 # diff ignoring all whitespace changes except leading whitespace changes
1934 assert_equal('', diff(['abc def'], ['abc def '], {iwhite: true}))
1935 assert_equal("@@ -1 +1 @@\n- abc\n+ xxx\n", diff([' abc'], [' xxx'], {iwhite: v:true}))
1936 assert_equal("@@ -1 +1 @@\n- abc\n+ xxx\n", diff([' abc'], [' xxx'], {iwhite: v:false}))
1937 assert_equal("@@ -1 +1 @@\n-abc \n+xxx \n", diff(['abc '], ['xxx '], {iwhite: v:true}))
1938 assert_equal("@@ -1 +1 @@\n-abc \n+xxx \n", diff(['abc '], ['xxx '], {iwhite: v:false}))
1939
1940 # diff ignoring all whitespace changes
1941 assert_equal('', diff(['abc def'], [' abc def '], {iwhiteall: true}))
1942 assert_equal("@@ -1 +1 @@\n- abc \n+ xxx \n", diff([' abc '], [' xxx '], {iwhiteall: v:true}))
1943 assert_equal("@@ -1 +1 @@\n- abc \n+ xxx \n", diff([' abc '], [' xxx '], {iwhiteall: v:false}))
1944
1945 # diff ignoring trailing whitespace changes
1946 assert_equal('', diff(['abc'], ['abc '], {iwhiteeol: true}))
1947
1948 # diff ignoring blank lines
1949 assert_equal('', diff(['one', '', '', 'two'], ['one', 'two'], {iblank: true}))
1950 assert_equal('', diff(['one', 'two'], ['one', '', '', 'two'], {iblank: true}))
1951
1952 # same string
1953 assert_equal('', diff(['abc', 'def', 'ghi'], ['abc', 'def', 'ghi']))
1954 assert_equal('', diff([''], ['']))
1955 assert_equal('', diff([], []))
1956
1957 # different xdiff algorithms
1958 for algo in ['myers', 'minimal', 'patience', 'histogram']
1959 assert_equal("@@ -1 +1 @@\n- abc \n+ xxx \n",
1960 diff([' abc '], [' xxx '], {algorithm: algo, output: 'unified'}))
1961 assert_equal([{from_idx: 0, from_count: 1, to_idx: 0, to_count: 1}],
1962 diff([' abc '], [' xxx '], {algorithm: algo, output: 'indices'}))
1963 endfor
1964 assert_equal("@@ -1 +1 @@\n- abc \n+ xxx \n",
1965 diff([' abc '], [' xxx '], {indent-heuristic: true, output: 'unified'}))
1966 assert_equal([{from_idx: 0, from_count: 1, to_idx: 0, to_count: 1}],
1967 diff([' abc '], [' xxx '], {indent-heuristic: true, output: 'indices'}))
1968
1969 # identical strings
1970 assert_equal('', diff(['111', '222'], ['111', '222'], {output: 'unified'}))
1971 assert_equal([], diff(['111', '222'], ['111', '222'], {output: 'indices'}))
1972 assert_equal('', diff([], [], {output: 'unified'}))
1973 assert_equal([], diff([], [], {output: 'indices'}))
1974
Yegappan Lakshmananbe156a32024-02-11 17:08:29 +01001975 # If 'diffexpr' is set, it should not be used for diff()
1976 def MyDiffExpr()
1977 enddef
1978 var save_diffexpr = &diffexpr
1979 :set diffexpr=MyDiffExpr()
1980 assert_equal("@@ -1 +1 @@\n-abc\n+\n",
1981 diff(['abc'], [''], {output: 'unified'}))
1982 assert_equal([{'from_idx': 0, 'from_count': 1, 'to_idx': 0, 'to_count': 1}],
1983 diff(['abc'], [''], {output: 'indices'}))
1984 assert_equal('MyDiffExpr()', &diffexpr)
1985 &diffexpr = save_diffexpr
1986
1987 # try different values for unified diff 'context'
1988 assert_equal("@@ -0,0 +1 @@\n+x\n",
1989 diff(['a', 'b', 'c'], ['x', 'a', 'b', 'c']))
1990 assert_equal("@@ -0,0 +1 @@\n+x\n",
1991 diff(['a', 'b', 'c'], ['x', 'a', 'b', 'c'], {context: 0}))
1992 assert_equal("@@ -1 +1,2 @@\n+x\n a\n",
1993 diff(['a', 'b', 'c'], ['x', 'a', 'b', 'c'], {context: 1}))
1994 assert_equal("@@ -1,2 +1,3 @@\n+x\n a\n b\n",
1995 diff(['a', 'b', 'c'], ['x', 'a', 'b', 'c'], {context: 2}))
1996 assert_equal("@@ -1,3 +1,4 @@\n+x\n a\n b\n c\n",
1997 diff(['a', 'b', 'c'], ['x', 'a', 'b', 'c'], {context: 3}))
1998 assert_equal("@@ -1,3 +1,4 @@\n+x\n a\n b\n c\n",
1999 diff(['a', 'b', 'c'], ['x', 'a', 'b', 'c'], {context: 4}))
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01002000 assert_equal("@@ -0,0 +1 @@\n+x\n",
Yegappan Lakshmananbe156a32024-02-11 17:08:29 +01002001 diff(['a', 'b', 'c'], ['x', 'a', 'b', 'c'], {context: -1}))
2002
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01002003 # Error cases
2004 assert_fails('call diff({}, ["a"])', 'E1211:')
2005 assert_fails('call diff(["a"], {})', 'E1211:')
2006 assert_fails('call diff(["a"], ["a"], [])', 'E1206:')
2007 assert_fails('call diff(["a"], ["a"], {output: "xyz"})', 'E106: Unsupported diff output format: xyz')
Yegappan Lakshmananbe156a32024-02-11 17:08:29 +01002008 assert_fails('call diff(["a"], ["a"], {context: []})', 'E745: Using a List as a Number')
Yegappan Lakshmananfa378352024-02-01 22:05:27 +01002009enddef
Bram Moolenaara315ce12022-06-24 12:38:57 +01002010
Yegappan Lakshmanana0010a12024-02-12 20:21:26 +01002011" Test for using the diff() function with 'diffexpr'
2012func Test_diffexpr_with_diff_func()
2013 CheckScreendump
2014
2015 let lines =<< trim END
2016 def DiffFuncExpr()
2017 var in: list<string> = readfile(v:fname_in)
2018 var new: list<string> = readfile(v:fname_new)
2019 var out: string = diff(in, new)
2020 writefile(split(out, "\n"), v:fname_out)
2021 enddef
2022 set diffexpr=DiffFuncExpr()
2023
2024 edit Xdifffunc1.txt
2025 diffthis
2026 vert split Xdifffunc2.txt
2027 diffthis
2028 END
2029 call writefile(lines, 'XsetupDiffFunc.vim', 'D')
2030
2031 call writefile(['zero', 'one', 'two', 'three'], 'Xdifffunc1.txt', 'D')
2032 call writefile(['one', 'twox', 'three', 'four'], 'Xdifffunc2.txt', 'D')
2033
2034 let buf = RunVimInTerminal('-S XsetupDiffFunc.vim', {'rows': 12})
2035 call VerifyScreenDump(buf, 'Test_difffunc_diffexpr_1', {})
2036 call StopVimInTerminal(buf)
2037endfunc
2038
zeertzjq9e7f1fc2024-03-16 09:40:22 +01002039func Test_diff_toggle_wrap_skipcol_leftcol()
2040 61vnew
2041 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.')
2042 30vnew
2043 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.')
2044 let win1 = win_getid()
2045 setlocal smoothscroll
2046 exe "normal! $\<C-E>"
2047 wincmd l
2048 let win2 = win_getid()
2049 setlocal smoothscroll
2050 exe "normal! $\<C-E>"
2051 call assert_equal([
2052 \ '<<<sadipscing elitr, sed diam |<<<tetur sadipscing elitr, sed|',
2053 \ 'nonumy eirmod tempor invidunt | diam nonumy eirmod tempor inv|',
2054 \ 'ut labore et dolore magna aliq|idunt ut labore et dolore magn|',
2055 \ 'uyam erat, sed diam voluptua. |a aliquyam erat, sed diam volu|',
2056 \ '~ |ptua. |',
2057 \ ], ScreenLines([1, 5], 62))
2058 call assert_equal({'col': 29, 'row': 4, 'endcol': 29, 'curscol': 29},
2059 \ screenpos(win1, line('.', win1), col('.', win1)))
2060 call assert_equal({'col': 36, 'row': 5, 'endcol': 36, 'curscol': 36},
2061 \ screenpos(win2, line('.', win2), col('.', win2)))
2062
2063 wincmd h
2064 diffthis
2065 wincmd l
2066 diffthis
2067 normal! 0
2068 call assert_equal([
2069 \ ' ipsum dolor sit amet, conset| Lorem ipsum dolor sit amet, |',
2070 \ '~ |~ |',
2071 \ ], ScreenLines([1, 2], 62))
2072 call assert_equal({'col': 3, 'row': 1, 'endcol': 3, 'curscol': 3},
2073 \ screenpos(win1, line('.', win1), col('.', win1)))
2074 call assert_equal({'col': 34, 'row': 1, 'endcol': 34, 'curscol': 34},
2075 \ screenpos(win2, line('.', win2), col('.', win2)))
2076
2077 normal! $
2078 call assert_equal([
2079 \ ' voluptua. | diam voluptua. |',
2080 \ '~ |~ |',
2081 \ ], ScreenLines([1, 2], 62))
2082 call assert_equal({'col': 11, 'row': 1, 'endcol': 11, 'curscol': 11},
2083 \ screenpos(win1, line('.', win1), col('.', win1)))
2084 call assert_equal({'col': 48, 'row': 1, 'endcol': 48, 'curscol': 48},
2085 \ screenpos(win2, line('.', win2), col('.', win2)))
2086
2087 diffoff!
2088 call assert_equal([
2089 \ 'ipsum dolor sit amet, consetet|Lorem ipsum dolor sit amet, co|',
2090 \ 'ur sadipscing elitr, sed diam |nsetetur sadipscing elitr, sed|',
2091 \ 'nonumy eirmod tempor invidunt | diam nonumy eirmod tempor inv|',
2092 \ 'ut labore et dolore magna aliq|idunt ut labore et dolore magn|',
2093 \ 'uyam erat, sed diam voluptua. |a aliquyam erat, sed diam volu|',
2094 \ '~ |ptua. |',
2095 \ ], ScreenLines([1, 6], 62))
2096 call assert_equal({'col': 29, 'row': 5, 'endcol': 29, 'curscol': 29},
2097 \ screenpos(win1, line('.', win1), col('.', win1)))
2098 call assert_equal({'col': 36, 'row': 6, 'endcol': 36, 'curscol': 36},
2099 \ screenpos(win2, line('.', win2), col('.', win2)))
2100
2101 bwipe!
2102 bwipe!
2103endfunc
2104
Luuk van Baal9148ba82024-04-08 22:27:41 +02002105" Ctrl-D reveals filler lines below the last line in the buffer.
2106func Test_diff_eob_halfpage()
Luuk van Baal08b0f632024-04-09 22:43:49 +02002107 new
Luuk van Baal9148ba82024-04-08 22:27:41 +02002108 call setline(1, ['']->repeat(10) + ['a'])
2109 diffthis
Luuk van Baal08b0f632024-04-09 22:43:49 +02002110 new
Luuk van Baal9148ba82024-04-08 22:27:41 +02002111 call setline(1, ['']->repeat(3) + ['a', 'b'])
2112 diffthis
Luuk van Baal08b0f632024-04-09 22:43:49 +02002113 resize 5
Luuk van Baal9148ba82024-04-08 22:27:41 +02002114 wincmd j
Luuk van Baal08b0f632024-04-09 22:43:49 +02002115 resize 5
2116 norm G
2117 call assert_equal(7, line('w0'))
2118 exe "norm! \<C-D>"
2119 call assert_equal(8, line('w0'))
Luuk van Baal9148ba82024-04-08 22:27:41 +02002120
2121 %bwipe!
2122endfunc
2123
Yukihiro Nakadaira06fe70c2024-09-26 16:19:42 +02002124func Test_diff_overlapped_diff_blocks_will_be_merged()
2125 CheckScreendump
2126
2127 let lines =<< trim END
2128 func DiffExprStub()
2129 let txt_in = readfile(v:fname_in)
2130 let txt_new = readfile(v:fname_new)
2131 if txt_in == ["line1"] && txt_new == ["line2"]
2132 call writefile(["1c1"], v:fname_out)
2133 elseif txt_in == readfile("Xdiin1") && txt_new == readfile("Xdinew1")
2134 call writefile(readfile("Xdiout1"), v:fname_out)
2135 elseif txt_in == readfile("Xdiin2") && txt_new == readfile("Xdinew2")
2136 call writefile(readfile("Xdiout2"), v:fname_out)
2137 endif
2138 endfunc
2139 END
2140 call writefile(lines, 'XdiffSetup', 'D')
2141
2142 call WriteDiffFiles(0, [], [])
2143 let buf = RunVimInTerminal('-d -S XdiffSetup Xdifile1 Xdifile2', {})
2144 call term_sendkeys(buf, ":set autoread\<CR>\<c-w>w:set autoread\<CR>\<c-w>w")
2145
2146 call WriteDiffFiles(buf, ["a", "b"], ["x", "x"])
2147 call writefile(["a", "b"], "Xdiin1")
2148 call writefile(["x", "x"], "Xdinew1")
2149 call writefile(["1c1", "2c2"], "Xdiout1")
2150 call term_sendkeys(buf, ":set diffexpr=DiffExprStub()\<CR>:")
2151 call VerifyBoth(buf, "Test_diff_overlapped_2.01", "")
2152 call term_sendkeys(buf, ":set diffexpr&\<CR>:")
2153
2154 call WriteDiffFiles(buf, ["a", "b", "c"], ["x", "c"])
2155 call writefile(["a", "b", "c"], "Xdiin1")
2156 call writefile(["x", "c"], "Xdinew1")
2157 call writefile(["1c1", "2d1"], "Xdiout1")
2158 call term_sendkeys(buf, ":set diffexpr=DiffExprStub()\<CR>:")
2159 call VerifyBoth(buf, "Test_diff_overlapped_2.02", "")
2160 call term_sendkeys(buf, ":set diffexpr&\<CR>:")
2161
2162 call WriteDiffFiles(buf, ["a", "c"], ["x", "x", "c"])
2163 call writefile(["a", "c"], "Xdiin1")
2164 call writefile(["x", "x", "c"], "Xdinew1")
2165 call writefile(["1c1", "1a2"], "Xdiout1")
2166 call term_sendkeys(buf, ":set diffexpr=DiffExprStub()\<CR>:")
2167 call VerifyBoth(buf, "Test_diff_overlapped_2.03", "")
2168 call term_sendkeys(buf, ":set diffexpr&\<CR>:")
2169
2170 call StopVimInTerminal(buf)
2171 wincmd c
2172
2173 call WriteDiffFiles3(0, [], [], [])
2174 let buf = RunVimInTerminal('-d -S XdiffSetup Xdifile1 Xdifile2 Xdifile3', {})
2175 call term_sendkeys(buf, ":set autoread\<CR>\<c-w>w:set autoread\<CR>\<c-w>w:set autoread\<CR>\<c-w>w")
2176
2177 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["y", "b", "c"])
2178 call VerifyBoth(buf, "Test_diff_overlapped_3.01", "")
2179
2180 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["a", "y", "c"])
2181 call VerifyBoth(buf, "Test_diff_overlapped_3.02", "")
2182
2183 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["a", "b", "y"])
2184 call VerifyBoth(buf, "Test_diff_overlapped_3.03", "")
2185
2186 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["y", "y", "c"])
2187 call VerifyBoth(buf, "Test_diff_overlapped_3.04", "")
2188
2189 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["a", "y", "y"])
2190 call VerifyBoth(buf, "Test_diff_overlapped_3.05", "")
2191
2192 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["y", "y", "y"])
2193 call VerifyBoth(buf, "Test_diff_overlapped_3.06", "")
2194
2195 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "x"], ["y", "y", "c"])
2196 call VerifyBoth(buf, "Test_diff_overlapped_3.07", "")
2197
2198 call WriteDiffFiles3(buf, ["a", "b", "c"], ["x", "x", "c"], ["a", "y", "y"])
2199 call VerifyBoth(buf, "Test_diff_overlapped_3.08", "")
2200
2201 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["y", "y", "y", "d", "e"])
2202 call VerifyBoth(buf, "Test_diff_overlapped_3.09", "")
2203
2204 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["y", "y", "y", "y", "e"])
2205 call VerifyBoth(buf, "Test_diff_overlapped_3.10", "")
2206
2207 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["y", "y", "y", "y", "y"])
2208 call VerifyBoth(buf, "Test_diff_overlapped_3.11", "")
2209
2210 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "y", "y", "d", "e"])
2211 call VerifyBoth(buf, "Test_diff_overlapped_3.12", "")
2212
2213 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "y", "y", "y", "e"])
2214 call VerifyBoth(buf, "Test_diff_overlapped_3.13", "")
2215
2216 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "y", "y", "y", "y"])
2217 call VerifyBoth(buf, "Test_diff_overlapped_3.14", "")
2218
2219 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "b", "y", "d", "e"])
2220 call VerifyBoth(buf, "Test_diff_overlapped_3.15", "")
2221
2222 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "b", "y", "y", "e"])
2223 call VerifyBoth(buf, "Test_diff_overlapped_3.16", "")
2224
2225 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "b", "y", "y", "y"])
2226 call VerifyBoth(buf, "Test_diff_overlapped_3.17", "")
2227
2228 call WriteDiffFiles3(buf, ["a", "b"], ["x", "b"], ["y", "y"])
2229 call writefile(["a", "b"], "Xdiin1")
2230 call writefile(["x", "b"], "Xdinew1")
2231 call writefile(["1c1"], "Xdiout1")
2232 call writefile(["a", "b"], "Xdiin2")
2233 call writefile(["y", "y"], "Xdinew2")
2234 call writefile(["1c1", "2c2"], "Xdiout2")
2235 call term_sendkeys(buf, ":set diffexpr=DiffExprStub()\<CR>:")
2236 call VerifyInternal(buf, "Test_diff_overlapped_3.18", "")
2237 call term_sendkeys(buf, ":set diffexpr&\<CR>:")
2238
2239 call WriteDiffFiles3(buf, ["a", "b", "c", "d"], ["x", "b", "x", "d"], ["y", "y", "c", "d"])
2240 call writefile(["a", "b", "c", "d"], "Xdiin1")
2241 call writefile(["x", "b", "x", "d"], "Xdinew1")
2242 call writefile(["1c1", "3c3"], "Xdiout1")
2243 call writefile(["a", "b", "c", "d"], "Xdiin2")
2244 call writefile(["y", "y", "c", "d"], "Xdinew2")
2245 call writefile(["1c1", "2c2"], "Xdiout2")
2246 call term_sendkeys(buf, ":set diffexpr=DiffExprStub()\<CR>:")
2247 call VerifyInternal(buf, "Test_diff_overlapped_3.19", "")
2248 call term_sendkeys(buf, ":set diffexpr&\<CR>:")
2249
2250 call WriteDiffFiles3(buf, ["a", "b", "c", "d"], ["x", "b", "x", "d"], ["y", "y", "y", "d"])
2251 call writefile(["a", "b", "c", "d"], "Xdiin1")
2252 call writefile(["x", "b", "x", "d"], "Xdinew1")
2253 call writefile(["1c1", "3c3"], "Xdiout1")
2254 call writefile(["a", "b", "c", "d"], "Xdiin2")
2255 call writefile(["y", "y", "y", "d"], "Xdinew2")
2256 call writefile(["1c1", "2,3c2,3"], "Xdiout2")
2257 call term_sendkeys(buf, ":set diffexpr=DiffExprStub()\<CR>:")
2258 call VerifyInternal(buf, "Test_diff_overlapped_3.20", "")
2259 call term_sendkeys(buf, ":set diffexpr&\<CR>:")
2260
2261 call WriteDiffFiles3(buf, ["a", "b", "c", "d"], ["x", "b", "x", "d"], ["y", "y", "y", "y"])
2262 call writefile(["a", "b", "c", "d"], "Xdiin1")
2263 call writefile(["x", "b", "x", "d"], "Xdinew1")
2264 call writefile(["1c1", "3c3"], "Xdiout1")
2265 call writefile(["a", "b", "c", "d"], "Xdiin2")
2266 call writefile(["y", "y", "y", "y"], "Xdinew2")
2267 call writefile(["1c1", "2,4c2,4"], "Xdiout2")
2268 call term_sendkeys(buf, ":set diffexpr=DiffExprStub()\<CR>:")
2269 call VerifyInternal(buf, "Test_diff_overlapped_3.21", "")
2270 call term_sendkeys(buf, ":set diffexpr&\<CR>:")
2271
2272 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["b", "c"])
2273 call VerifyBoth(buf, "Test_diff_overlapped_3.22", "")
2274
2275 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["c"])
2276 call VerifyBoth(buf, "Test_diff_overlapped_3.23", "")
2277
2278 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], [])
2279 call VerifyBoth(buf, "Test_diff_overlapped_3.24", "")
2280
2281 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["a", "c"])
2282 call VerifyBoth(buf, "Test_diff_overlapped_3.25", "")
2283
2284 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["a"])
2285 call VerifyBoth(buf, "Test_diff_overlapped_3.26", "")
2286
2287 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["b"])
2288 call VerifyBoth(buf, "Test_diff_overlapped_3.27", "")
2289
2290 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["d", "e"])
2291 call VerifyBoth(buf, "Test_diff_overlapped_3.28", "")
2292
2293 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["e"])
2294 call VerifyBoth(buf, "Test_diff_overlapped_3.29", "")
2295
2296 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "d", "e"])
2297 call VerifyBoth(buf, "Test_diff_overlapped_3.30", "")
2298
2299 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "e"])
2300 call VerifyBoth(buf, "Test_diff_overlapped_3.31", "")
2301
2302 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a"])
2303 call VerifyBoth(buf, "Test_diff_overlapped_3.32", "")
2304
2305 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "b", "d", "e"])
2306 call VerifyBoth(buf, "Test_diff_overlapped_3.33", "")
2307
2308 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "b", "e"])
2309 call VerifyBoth(buf, "Test_diff_overlapped_3.34", "")
2310
2311 call WriteDiffFiles3(buf, ["a", "b", "c", "d", "e"], ["a", "x", "c", "x", "e"], ["a", "b"])
2312 call VerifyBoth(buf, "Test_diff_overlapped_3.35", "")
2313
2314 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["a", "y", "b", "c"])
2315 call VerifyBoth(buf, "Test_diff_overlapped_3.36", "")
2316
2317 call WriteDiffFiles3(buf, ["a", "b", "c"], ["a", "x", "c"], ["a", "b", "y", "c"])
2318 call VerifyBoth(buf, "Test_diff_overlapped_3.37", "")
2319
Yukihiro Nakadaira01f65092025-01-15 18:36:43 +01002320 call WriteDiffFiles3(buf, ["a", "b", "c"], ["d", "e"], ["b", "f"])
2321 call VerifyBoth(buf, "Test_diff_overlapped_3.38", "")
2322
2323 call WriteDiffFiles3(buf, ["a", "b", "c"], ["d", "e"], ["b"])
2324 call VerifyBoth(buf, "Test_diff_overlapped_3.39", "")
2325
Yee Cheng Chinbc08ceb2025-03-02 22:05:37 +01002326 " File 3 overlaps twice, 2nd overlap completely within the existing block.
2327 call WriteDiffFiles3(buf, ["foo", "a", "b", "c", "bar"], ["foo", "w", "x", "y", "z", "bar"], ["foo", "1", "a", "b", "2", "bar"])
2328 call VerifyBoth(buf, "Test_diff_overlapped_3.40", "")
2329
2330 " File 3 overlaps twice, 2nd overlap extends beyond existing block on new
2331 " side. Make sure we don't over-extend the range and hit 'bar'.
2332 call WriteDiffFiles3(buf, ["foo", "a", "b", "c", "d", "bar"], ["foo", "w", "x", "y", "z", "u", "bar"], ["foo", "1", "a", "b", "2", "d", "bar"])
2333 call VerifyBoth(buf, "Test_diff_overlapped_3.41", "")
2334
2335 " Chained overlaps. File 3's 2nd overlap spans two diff blocks and is longer
2336 " than the 2nd one.
2337 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"])
2338 call VerifyBoth(buf, "Test_diff_overlapped_3.42", "")
2339
2340 " File 3 has 2 overlaps. An add and a delete. First overlap's expansion hits
2341 " the 2nd one. Make sure we adjust the diff block to have fewer lines.
2342 call WriteDiffFiles3(buf, ["foo", "a", "b", "bar"], ["foo", "x", "y", "bar"], ["foo", "1", "a", "bar"])
2343 call VerifyBoth(buf, "Test_diff_overlapped_3.43", "")
2344
2345 " File 3 has 2 overlaps. An add and another add. First overlap's expansion hits
2346 " the 2nd one. Make sure we adjust the diff block to have more lines.
2347 call WriteDiffFiles3(buf, ["foo", "a", "b", "c", "d", "bar"], ["foo", "w", "x", "y", "z", "u", "bar"], ["foo", "1", "a", "b", "3", "4", "d", "bar"])
2348 call VerifyBoth(buf, "Test_diff_overlapped_3.44", "")
2349
Yukihiro Nakadaira06fe70c2024-09-26 16:19:42 +02002350 call StopVimInTerminal(buf)
2351endfunc
2352
zeertzjq7c515282024-11-10 20:26:12 +01002353" switching windows in diff mode caused an unnecessary scroll
Christian Brabandt05a40e02024-10-29 20:29:04 +01002354func Test_diff_topline_noscroll()
2355 CheckScreendump
2356
2357 let content =<< trim END
2358 call setline(1, range(1,60))
2359 vnew
2360 call setline(1, range(1,10) + range(50,60))
2361 windo diffthis
2362 norm! G
2363 exe "norm! 30\<C-y>"
2364 END
2365 call writefile(content, 'Xcontent', 'D')
2366 let buf = RunVimInTerminal('-S Xcontent', {'rows': 20})
2367 call VerifyScreenDump(buf, 'Test_diff_topline_1', {})
2368 call term_sendkeys(buf, ":echo line('w0', 1001)\<cr>")
2369 call term_wait(buf)
2370 call VerifyScreenDump(buf, 'Test_diff_topline_2', {})
2371 call term_sendkeys(buf, "\<C-W>p")
2372 call term_wait(buf)
2373 call VerifyScreenDump(buf, 'Test_diff_topline_3', {})
2374 call term_sendkeys(buf, "\<C-W>p")
2375 call term_wait(buf)
2376 call VerifyScreenDump(buf, 'Test_diff_topline_4', {})
2377 call StopVimInTerminal(buf)
2378endfunc
2379
Yee Cheng Chin9943d472025-03-26 19:41:02 +01002380" Test inline highlighting which shows what's different within each diff block
2381func Test_diff_inline()
2382 CheckScreendump
2383
2384 call WriteDiffFiles(0, [], [])
2385 let buf = RunVimInTerminal('-d Xdifile1 Xdifile2', {})
2386 call term_sendkeys(buf, ":set autoread\<CR>\<c-w>w:set autoread\<CR>\<c-w>w")
2387
2388 call WriteDiffFiles(buf, ["abcdef ghi jk n", "x", "y"], ["aBcef gHi lm n", "y", "z"])
2389 call VerifyInternal(buf, "Test_diff_inline_01", "")
2390 call VerifyInternal(buf, "Test_diff_inline_02", " diffopt+=inline:none")
2391
2392 " inline:simple is the same as default
2393 call VerifyInternal(buf, "Test_diff_inline_01", " diffopt+=inline:simple")
2394
2395 call VerifyInternal(buf, "Test_diff_inline_03", " diffopt+=inline:char")
2396 call VerifyInternal(buf, "Test_diff_inline_04", " diffopt+=inline:word")
2397
2398 " multiple inline values will the last one
2399 call VerifyInternal(buf, "Test_diff_inline_01", " diffopt+=inline:none,inline:char,inline:simple")
2400 call VerifyInternal(buf, "Test_diff_inline_02", " diffopt+=inline:simple,inline:word,inline:none")
2401 call VerifyInternal(buf, "Test_diff_inline_03", " diffopt+=inline:simple,inline:word,inline:char")
2402
2403 " DiffTextAdd highlight
2404 call term_sendkeys(buf, ":hi DiffTextAdd ctermbg=blue\<CR>")
2405 call VerifyInternal(buf, "Test_diff_inline_05", " diffopt+=inline:char")
2406
2407 " Live update in insert mode
2408 call term_sendkeys(buf, "\<Esc>isometext")
2409 call VerifyScreenDump(buf, "Test_diff_inline_06", {})
2410 call term_sendkeys(buf, "\<Esc>u")
2411
2412 " icase simple scenarios
2413 call VerifyInternal(buf, "Test_diff_inline_07", " diffopt+=inline:simple,icase")
2414 call VerifyInternal(buf, "Test_diff_inline_08", " diffopt+=inline:char,icase")
2415 call VerifyInternal(buf, "Test_diff_inline_09", " diffopt+=inline:word,icase")
2416
2417 " diff algorithms should affect highlight
2418 call WriteDiffFiles(buf, ["apples and oranges"], ["oranges and apples"])
2419 call VerifyInternal(buf, "Test_diff_inline_10", " diffopt+=inline:char")
2420 call VerifyInternal(buf, "Test_diff_inline_11", " diffopt+=inline:char,algorithm:patience")
2421
2422 " icase: composing chars and Unicode fold case edge cases
2423 call WriteDiffFiles(buf,
2424 \ ["1 - sigma in 6σ and Ὀδυσσεύς", "1 - angstrom in åå", "1 - composing: ii⃗I⃗"],
2425 \ ["2 - Sigma in 6Σ and ὈΔΥΣΣΕΎΣ", "2 - Angstrom in ÅÅ", "2 - Composing: i⃗I⃗I⃗"])
2426 call VerifyInternal(buf, "Test_diff_inline_12", " diffopt+=inline:char")
2427 call VerifyInternal(buf, "Test_diff_inline_13", " diffopt+=inline:char,icase")
2428
2429 " wide chars
2430 call WriteDiffFiles(buf, ["abc😅xde一", "f🚀g"], ["abcy😢de", "二f🚀g"])
2431 call VerifyInternal(buf, "Test_diff_inline_14", " diffopt+=inline:char,icase")
2432
2433 " NUL char (\n below is internally substituted as NUL)
2434 call WriteDiffFiles(buf, ["1\n34\n5\n6"], ["1234\n5", "6"])
2435 call VerifyInternal(buf, "Test_diff_inline_15", " diffopt+=inline:char")
2436
2437 " word diff: always use first buffer's iskeyword and ignore others' for consistency
2438 call WriteDiffFiles(buf, ["foo+bar test"], ["foo+baz test"])
2439 call VerifyInternal(buf, "Test_diff_inline_word_01", " diffopt+=inline:word")
2440
2441 call term_sendkeys(buf, ":set iskeyword+=+\<CR>:diffupdate\<CR>")
2442 call VerifyInternal(buf, "Test_diff_inline_word_02", " diffopt+=inline:word")
2443
2444 call term_sendkeys(buf, ":set iskeyword&\<CR>:wincmd w\<CR>")
2445 call term_sendkeys(buf, ":set iskeyword+=+\<CR>:wincmd w\<CR>:diffupdate\<CR>")
2446 " Use the previous screen dump as 2nd buffer's iskeyword does not matter
2447 call VerifyInternal(buf, "Test_diff_inline_word_01", " diffopt+=inline:word")
2448
2449 call term_sendkeys(buf, ":windo set iskeyword&\<CR>:1wincmd w\<CR>")
2450
Yee Cheng Chin9aa120f2025-04-04 19:16:21 +02002451 " word diff: test handling of multi-byte characters. Only alphanumeric chars
2452 " (e.g. Greek alphabet, but not CJK/emoji) count as words.
2453 call WriteDiffFiles(buf, ["🚀⛵️一二三ひらがなΔέλτα Δelta foobar"], ["🚀🛸一二四ひらなδέλτα δelta foobar"])
2454 call VerifyInternal(buf, "Test_diff_inline_word_03", " diffopt+=inline:word")
2455
Yee Cheng Chin9943d472025-03-26 19:41:02 +01002456 " char diff: should slide highlight to whitespace boundary if possible for
2457 " better readability (by using forced indent-heuristics). A wrong result
2458 " would be if the highlight is "Bar, prefix". It should be "prefixBar, "
2459 " instead.
2460 call WriteDiffFiles(buf, ["prefixFoo, prefixEnd"], ["prefixFoo, prefixBar, prefixEnd"])
2461 call VerifyInternal(buf, "Test_diff_inline_char_01", " diffopt+=inline:char")
2462
2463 " char diff: small gaps between inline diff blocks will be merged during refine step
2464 " - first segment: test that we iteratively merge small gaps after we merged
2465 " adjacent blocks, but only with limited number (set to 4) of iterations.
2466 " - second and third segments: show that we need a large enough adjacent block to
2467 " trigger a merge.
2468 " - fourth segment: small gaps are not merged when adjacent large block is
2469 " on a different line.
2470 call WriteDiffFiles(buf,
2471 \ ["abcdefghijklmno", "anchor1",
2472 \ "abcdefghijklmno", "anchor2",
2473 \ "abcdefghijklmno", "anchor3",
2474 \ "test", "multiline"],
zeertzjq5a307c32025-03-28 19:01:32 +01002475 \ ["a?c?e?g?i?k???o", "anchor1",
2476 \ "a??de?????klmno", "anchor2",
Yee Cheng Chin9943d472025-03-26 19:41:02 +01002477 \ "a??de??????lmno", "anchor3",
2478 \ "t?s?", "??????i?e"])
2479 call VerifyInternal(buf, "Test_diff_inline_char_02", " diffopt+=inline:char")
2480
2481 " Test multi-line blocks and whitespace
2482 call WriteDiffFiles(buf,
2483 \ ["this is ", "sometest text foo", "baz abc def ", "one", "word another word", "additional line"],
2484 \ ["this is some test", "texts", "foo bar abX Yef ", "oneword another word"])
2485 call VerifyInternal(buf, "Test_diff_inline_multiline_01", " diffopt+=inline:char,iwhite")
2486 call VerifyInternal(buf, "Test_diff_inline_multiline_02", " diffopt+=inline:word,iwhite")
2487 call VerifyInternal(buf, "Test_diff_inline_multiline_03", " diffopt+=inline:char,iwhiteeol")
2488 call VerifyInternal(buf, "Test_diff_inline_multiline_04", " diffopt+=inline:word,iwhiteeol")
2489 call VerifyInternal(buf, "Test_diff_inline_multiline_05", " diffopt+=inline:char,iwhiteall")
2490 call VerifyInternal(buf, "Test_diff_inline_multiline_06", " diffopt+=inline:word,iwhiteall")
2491
2492 " newline should be highlighted too when 'list' is set
2493 call term_sendkeys(buf, ":windo set list\<CR>")
2494 call VerifyInternal(buf, "Test_diff_inline_multiline_07", " diffopt+=inline:char")
2495 call VerifyInternal(buf, "Test_diff_inline_multiline_08", " diffopt+=inline:char,iwhite")
2496 call VerifyInternal(buf, "Test_diff_inline_multiline_09", " diffopt+=inline:char,iwhiteeol")
2497 call VerifyInternal(buf, "Test_diff_inline_multiline_10", " diffopt+=inline:char,iwhiteall")
2498 call term_sendkeys(buf, ":windo set nolist\<CR>")
2499
2500 call StopVimInTerminal(buf)
2501endfunc
2502
2503func Test_diff_inline_multibuffer()
2504 CheckScreendump
2505
2506 call WriteDiffFiles3(0, [], [], [])
2507 let buf = RunVimInTerminal('-d Xdifile1 Xdifile2 Xdifile3', {})
2508 call term_sendkeys(buf, ":windo set autoread\<CR>:1wincmd w\<CR>")
2509 call term_sendkeys(buf, ":hi DiffTextAdd ctermbg=blue\<CR>")
2510
2511 call WriteDiffFiles3(buf,
2512 \ ["That is buffer1.", "anchor", "Some random text", "anchor"],
2513 \ ["This is buffer2.", "anchor", "Some text", "anchor", "buffer2/3"],
2514 \ ["This is buffer3. Last.", "anchor", "Some more", "text here.", "anchor", "only in buffer2/3", "not in buffer1"])
2515 call VerifyInternal(buf, "Test_diff_inline_multibuffer_01", " diffopt+=inline:char")
2516
zeertzjq5a307c32025-03-28 19:01:32 +01002517 " Close one of the buffers and make sure it updates correctly
Yee Cheng Chin9943d472025-03-26 19:41:02 +01002518 call term_sendkeys(buf, ":diffoff\<CR>")
2519 call VerifyInternal(buf, "Test_diff_inline_multibuffer_02", " diffopt+=inline:char")
2520
2521 " Update text in the non-diff buffer and nothing should be changed
2522 call term_sendkeys(buf, "\<Esc>isometext")
2523 call VerifyScreenDump(buf, "Test_diff_inline_multibuffer_03", {})
2524 call term_sendkeys(buf, "\<Esc>u")
2525
2526 call term_sendkeys(buf, ":diffthis\<CR>")
2527 call VerifyInternal(buf, "Test_diff_inline_multibuffer_01", " diffopt+=inline:char")
2528
2529 " Test that removing first buffer from diff will in turn use the next
2530 " earliest buffer's iskeyword during word diff.
2531 call WriteDiffFiles3(buf,
2532 \ ["This+is=a-setence"],
2533 \ ["This+is=another-setence"],
2534 \ ["That+is=a-setence"])
2535 call term_sendkeys(buf, ":set iskeyword+=+\<CR>:2wincmd w\<CR>:set iskeyword+=-\<CR>:1wincmd w\<CR>")
2536 call VerifyInternal(buf, "Test_diff_inline_multibuffer_04", " diffopt+=inline:word")
2537 call term_sendkeys(buf, ":diffoff\<CR>")
2538 call VerifyInternal(buf, "Test_diff_inline_multibuffer_05", " diffopt+=inline:word")
2539 call term_sendkeys(buf, ":diffthis\<CR>")
2540 call VerifyInternal(buf, "Test_diff_inline_multibuffer_04", " diffopt+=inline:word")
2541
2542 " Test multi-buffer char diff refinement, and that removing a buffer from
2543 " diff will update the others properly.
2544 call WriteDiffFiles3(buf,
2545 \ ["abcdefghijkYmYYY"],
2546 \ ["aXXdXXghijklmnop"],
2547 \ ["abcdefghijkYmYop"])
2548 call VerifyInternal(buf, "Test_diff_inline_multibuffer_06", " diffopt+=inline:char")
2549 call term_sendkeys(buf, ":diffoff\<CR>")
2550 call VerifyInternal(buf, "Test_diff_inline_multibuffer_07", " diffopt+=inline:char")
2551 call term_sendkeys(buf, ":diffthis\<CR>")
2552 call VerifyInternal(buf, "Test_diff_inline_multibuffer_06", " diffopt+=inline:char")
2553
2554 call StopVimInTerminal(buf)
2555endfunc
2556
Jonathon7c7a4e62025-01-12 09:58:00 +01002557func Test_diffget_diffput_linematch()
2558 CheckScreendump
2559 call delete('.Xdifile1.swp')
2560 call delete('.Xdifile2.swp')
2561 call WriteDiffFiles(0, [], [])
2562 let buf = RunVimInTerminal('-d Xdifile1 Xdifile2', {})
2563 call term_sendkeys(buf, ":set autoread\<CR>\<c-w>w:set autoread\<CR>\<c-w>w")
2564
2565 " enable linematch
2566 call term_sendkeys(buf, ":set diffopt+=linematch:30\<CR>")
2567 call WriteDiffFiles(buf, ['',
2568 \ 'common line',
2569 \ 'common line',
2570 \ '',
2571 \ 'ABCabc',
2572 \ 'ABCabc',
2573 \ 'ABCabc',
2574 \ 'ABCabc',
2575 \ 'common line',
2576 \ 'common line',
2577 \ 'common line',
2578 \ 'something' ],
2579 \ ['',
2580 \ 'common line',
2581 \ 'common line',
2582 \ '',
2583 \ 'DEFabc',
2584 \ 'xyz',
2585 \ 'xyz',
2586 \ 'xyz',
2587 \ 'DEFabc',
2588 \ 'DEFabc',
2589 \ 'DEFabc',
2590 \ 'common line',
2591 \ 'common line',
2592 \ 'DEF',
2593 \ 'common line',
2594 \ 'DEF',
2595 \ 'something'])
2596 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_1', {})
2597
2598 " get from window 1 from line 5 to 9
2599 call term_sendkeys(buf, "1\<c-w>w")
2600 call term_sendkeys(buf, ":5,9diffget\<CR>")
2601 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_2', {})
2602
2603 " undo the last diffget
2604 call term_sendkeys(buf, "u")
2605
2606 " get from window 2 from line 5 to 10
2607 call term_sendkeys(buf, "2\<c-w>w")
2608 call term_sendkeys(buf, ":5,10diffget\<CR>")
2609 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_3', {})
2610
2611 " undo the last diffget
2612 call term_sendkeys(buf, "u")
2613
2614 " get all from window 2
2615 call term_sendkeys(buf, "2\<c-w>w")
2616 call term_sendkeys(buf, ":4,17diffget\<CR>")
2617 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_4', {})
2618
2619 " undo the last diffget
2620 call term_sendkeys(buf, "u")
2621
2622 " get all from window 1
2623 call term_sendkeys(buf, "1\<c-w>w")
2624 call term_sendkeys(buf, ":4,12diffget\<CR>")
2625 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_5', {})
2626
2627 " undo the last diffget
2628 call term_sendkeys(buf, "u")
2629
2630 " get from window 1 using do 1 line 5
2631 call term_sendkeys(buf, "1\<c-w>w")
2632 call term_sendkeys(buf, "5gg")
2633 call term_sendkeys(buf, ":diffget\<CR>")
2634 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_6', {})
2635
2636 " undo the last diffget
2637 call term_sendkeys(buf, "u")
2638
2639 " get from window 1 using do 2 line 6
2640 call term_sendkeys(buf, "1\<c-w>w")
2641 call term_sendkeys(buf, "6gg")
2642 call term_sendkeys(buf, ":diffget\<CR>")
2643 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_7', {})
2644
2645 " undo the last diffget
2646 call term_sendkeys(buf, "u")
2647
2648 " get from window 1 using do 2 line 7
2649 call term_sendkeys(buf, "1\<c-w>w")
2650 call term_sendkeys(buf, "7gg")
2651 call term_sendkeys(buf, ":diffget\<CR>")
2652 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_8', {})
2653
2654 " undo the last diffget
2655 call term_sendkeys(buf, "u")
2656
2657 " get from window 1 using do 2 line 11
2658 call term_sendkeys(buf, "1\<c-w>w")
2659 call term_sendkeys(buf, "11gg")
2660 call term_sendkeys(buf, ":diffget\<CR>")
2661 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_9', {})
2662
2663 " undo the last diffget
2664 call term_sendkeys(buf, "u")
2665
2666 " get from window 1 using do 2 line 12
2667 call term_sendkeys(buf, "1\<c-w>w")
2668 call term_sendkeys(buf, "12gg")
2669 call term_sendkeys(buf, ":diffget\<CR>")
2670 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_10', {})
2671
2672 " undo the last diffget
2673 call term_sendkeys(buf, "u")
2674
2675 " put from window 1 using dp 1 line 5
2676 call term_sendkeys(buf, "1\<c-w>w")
2677 call term_sendkeys(buf, "5gg")
2678 call term_sendkeys(buf, ":diffput\<CR>")
2679 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_11', {})
2680
2681 " undo the last diffput
2682 call term_sendkeys(buf, "2\<c-w>w")
2683 call term_sendkeys(buf, "u")
2684
2685 " put from window 1 using dp 2 line 6
2686 call term_sendkeys(buf, "1\<c-w>w")
2687 call term_sendkeys(buf, "6gg")
2688 call term_sendkeys(buf, ":diffput\<CR>")
2689 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_12', {})
2690
2691 " undo the last diffput
2692 call term_sendkeys(buf, "2\<c-w>w")
2693 call term_sendkeys(buf, "u")
2694
2695 " put from window 1 using dp 2 line 7
2696 call term_sendkeys(buf, "1\<c-w>w")
2697 call term_sendkeys(buf, "7gg")
2698 call term_sendkeys(buf, ":diffput\<CR>")
2699 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_13', {})
2700
2701 " undo the last diffput
2702 call term_sendkeys(buf, "2\<c-w>w")
2703 call term_sendkeys(buf, "u")
2704
2705 " put from window 1 using dp 2 line 11
2706 call term_sendkeys(buf, "1\<c-w>w")
2707 call term_sendkeys(buf, "11gg")
2708 call term_sendkeys(buf, ":diffput\<CR>")
2709 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_14', {})
2710
2711 " undo the last diffput
2712 call term_sendkeys(buf, "2\<c-w>w")
2713 call term_sendkeys(buf, "u")
2714
2715 " put from window 1 using dp 2 line 12
2716 call term_sendkeys(buf, "1\<c-w>w")
2717 call term_sendkeys(buf, "12gg")
2718 call term_sendkeys(buf, ":diffput\<CR>")
2719 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_15', {})
2720
2721 " undo the last diffput
2722 call term_sendkeys(buf, "2\<c-w>w")
2723 call term_sendkeys(buf, "u")
2724
2725 " put from window 2 using dp line 6
2726 call term_sendkeys(buf, "2\<c-w>w")
2727 call term_sendkeys(buf, "6gg")
2728 call term_sendkeys(buf, ":diffput\<CR>")
2729 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_16', {})
2730
2731 " undo the last diffput
2732 call term_sendkeys(buf, "1\<c-w>w")
2733 call term_sendkeys(buf, "u")
2734
2735 " put from window 2 using dp line 8
2736 call term_sendkeys(buf, "2\<c-w>w")
2737 call term_sendkeys(buf, "8gg")
2738 call term_sendkeys(buf, ":diffput\<CR>")
2739 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_17', {})
2740
2741 " undo the last diffput
2742 call term_sendkeys(buf, "1\<c-w>w")
2743 call term_sendkeys(buf, "u")
2744
2745 " put from window 2 using dp line 9
2746 call term_sendkeys(buf, "2\<c-w>w")
2747 call term_sendkeys(buf, "9gg")
2748 call term_sendkeys(buf, ":diffput\<CR>")
2749 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_18', {})
2750
2751 " undo the last diffput
2752 call term_sendkeys(buf, "1\<c-w>w")
2753 call term_sendkeys(buf, "u")
2754
2755 " put from window 2 using dp line 17
2756 call term_sendkeys(buf, "2\<c-w>w")
2757 call term_sendkeys(buf, "17gg")
2758 call term_sendkeys(buf, ":diffput\<CR>")
2759 call VerifyScreenDump(buf, 'Test_diff_get_put_linematch_19', {})
Jonathonca307ef2025-01-17 13:37:35 +01002760 " clean up
2761 call StopVimInTerminal(buf)
Jonathon7c7a4e62025-01-12 09:58:00 +01002762endfunc
2763
2764func Test_linematch_diff()
2765 CheckScreendump
2766 call delete('.Xdifile1.swp')
2767 call delete('.Xdifile2.swp')
2768 call WriteDiffFiles(0, [], [])
2769 let buf = RunVimInTerminal('-d Xdifile1 Xdifile2', {})
2770 call term_sendkeys(buf, ":set autoread\<CR>\<c-w>w:set autoread\<CR>\<c-w>w")
2771
2772 " enable linematch
2773 call term_sendkeys(buf, ":set diffopt+=linematch:30\<CR>")
2774 call WriteDiffFiles(buf, ['// abc d?',
2775 \ '// d?',
2776 \ '// d?' ],
2777 \ ['!',
2778 \ 'abc d!',
2779 \ 'd!'])
2780 call VerifyScreenDump(buf, 'Test_linematch_diff1', {})
Jonathonca307ef2025-01-17 13:37:35 +01002781 " clean up
2782 call StopVimInTerminal(buf)
Jonathon7c7a4e62025-01-12 09:58:00 +01002783endfunc
2784
2785func Test_linematch_diff_iwhite()
2786 CheckScreendump
2787 call delete('.Xdifile1.swp')
2788 call delete('.Xdifile2.swp')
2789 call WriteDiffFiles(0, [], [])
2790 let buf = RunVimInTerminal('-d Xdifile1 Xdifile2', {})
2791 call term_sendkeys(buf, ":set autoread\<CR>\<c-w>w:set autoread\<CR>\<c-w>w")
2792
2793 " setup a diff with 2 files and set linematch:30, with ignore white
2794 call term_sendkeys(buf, ":set diffopt+=linematch:30\<CR>")
2795 call WriteDiffFiles(buf, ['void testFunction () {',
2796 \ ' for (int i = 0; i < 10; i++) {',
2797 \ ' for (int j = 0; j < 10; j++) {',
2798 \ ' }',
2799 \ ' }',
2800 \ '}' ],
2801 \ ['void testFunction () {',
2802 \ ' // for (int j = 0; j < 10; i++) {',
2803 \ ' // }',
2804 \ '}'])
2805 call VerifyScreenDump(buf, 'Test_linematch_diff_iwhite1', {})
2806 call term_sendkeys(buf, ":set diffopt+=iwhiteall\<CR>")
2807 call VerifyScreenDump(buf, 'Test_linematch_diff_iwhite2', {})
Jonathonca307ef2025-01-17 13:37:35 +01002808 " clean up
2809 call StopVimInTerminal(buf)
Jonathon7c7a4e62025-01-12 09:58:00 +01002810endfunc
2811
2812func Test_linematch_diff_grouping()
2813 CheckScreendump
2814 call delete('.Xdifile1.swp')
2815 call delete('.Xdifile2.swp')
2816 call WriteDiffFiles(0, [], [])
2817 let buf = RunVimInTerminal('-d Xdifile1 Xdifile2', {})
2818 call term_sendkeys(buf, ":set autoread\<CR>\<c-w>w:set autoread\<CR>\<c-w>w")
2819
2820 " a diff that would result in multiple groups before grouping optimization
2821 call term_sendkeys(buf, ":set diffopt+=linematch:30\<CR>")
2822 call WriteDiffFiles(buf, ['!A',
2823 \ '!B',
2824 \ '!C' ],
2825 \ ['?Z',
2826 \ '?A',
2827 \ '?B',
2828 \ '?C',
2829 \ '?A',
2830 \ '?B',
2831 \ '?B',
2832 \ '?C'])
2833 call VerifyScreenDump(buf, 'Test_linematch_diff_grouping1', {})
2834 call WriteDiffFiles(buf, ['!A',
2835 \ '!B',
2836 \ '!C' ],
2837 \ ['?A',
2838 \ '?Z',
2839 \ '?B',
2840 \ '?C',
2841 \ '?A',
2842 \ '?B',
2843 \ '?C',
2844 \ '?C'])
2845 call VerifyScreenDump(buf, 'Test_linematch_diff_grouping2', {})
Jonathonca307ef2025-01-17 13:37:35 +01002846 " clean up
2847 call StopVimInTerminal(buf)
Jonathon7c7a4e62025-01-12 09:58:00 +01002848endfunc
2849
2850func Test_linematch_diff_scroll()
2851 CheckScreendump
2852 call delete('.Xdifile1.swp')
2853 call delete('.Xdifile2.swp')
2854 call WriteDiffFiles(0, [], [])
2855 let buf = RunVimInTerminal('-d Xdifile1 Xdifile2', {})
2856 call term_sendkeys(buf, ":set autoread\<CR>\<c-w>w:set autoread\<CR>\<c-w>w")
2857
2858 " a diff that would result in multiple groups before grouping optimization
2859 call term_sendkeys(buf, ":set diffopt+=linematch:30\<CR>")
2860 call WriteDiffFiles(buf, ['!A',
2861 \ '!B',
2862 \ '!C' ],
2863 \ ['?A',
2864 \ '?Z',
2865 \ '?B',
2866 \ '?C',
2867 \ '?A',
2868 \ '?B',
2869 \ '?C',
2870 \ '?C'])
2871 " scroll down to show calculation of top fill and scroll to correct line in
2872 " both windows
2873 call VerifyScreenDump(buf, 'Test_linematch_diff_grouping_scroll0', {})
2874 call term_sendkeys(buf, "3\<c-e>")
2875 call VerifyScreenDump(buf, 'Test_linematch_diff_grouping_scroll1', {})
2876 call term_sendkeys(buf, "3\<c-e>")
2877 call VerifyScreenDump(buf, 'Test_linematch_diff_grouping_scroll2', {})
Jonathonca307ef2025-01-17 13:37:35 +01002878 " clean up
2879 call StopVimInTerminal(buf)
Jonathon7c7a4e62025-01-12 09:58:00 +01002880endfunc
2881
Jonathon7c7a4e62025-01-12 09:58:00 +01002882func Test_linematch_line_limit_exceeded()
2883 CheckScreendump
2884 call delete('.Xdifile1.swp')
2885 call delete('.Xdifile2.swp')
2886 call WriteDiffFiles(0, [], [])
2887 let buf = RunVimInTerminal('-d Xdifile1 Xdifile2', {})
2888 call term_sendkeys(buf, ":set autoread\<CR>\<c-w>w:set autoread\<CR>\<c-w>w")
2889
2890 call term_sendkeys(buf, ":set diffopt+=linematch:10\<CR>")
2891 " a diff block will not be aligned with linematch because it's contents
2892 " exceed 10 lines
2893 call WriteDiffFiles(buf,
2894 \ ['common line',
2895 \ 'HIL',
2896 \ '',
2897 \ 'aABCabc',
2898 \ 'aABCabc',
2899 \ 'aABCabc',
2900 \ 'aABCabc',
2901 \ 'common line',
2902 \ 'HIL',
2903 \ 'common line',
2904 \ 'something'],
2905 \ ['common line',
2906 \ 'DEF',
2907 \ 'GHI',
2908 \ 'something',
2909 \ '',
2910 \ 'aDEFabc',
2911 \ 'xyz',
2912 \ 'xyz',
2913 \ 'xyz',
2914 \ 'aDEFabc',
2915 \ 'aDEFabc',
2916 \ 'aDEFabc',
2917 \ 'common line',
2918 \ 'DEF',
2919 \ 'GHI',
2920 \ 'something else',
2921 \ 'common line',
2922 \ 'something'])
2923 call VerifyScreenDump(buf, 'Test_linematch_line_limit_exceeded1', {})
2924 " after increasing the count to 30, the limit is not exceeded, and the
2925 " alignment algorithm will run on the largest diff block here
2926 call term_sendkeys(buf, ":set diffopt+=linematch:30\<CR>")
2927 call VerifyScreenDump(buf, 'Test_linematch_line_limit_exceeded2', {})
Jonathonca307ef2025-01-17 13:37:35 +01002928 " clean up
2929 call StopVimInTerminal(buf)
Jonathon7c7a4e62025-01-12 09:58:00 +01002930endfunc
2931
2932func Test_linematch_3diffs()
2933 CheckScreendump
2934 call delete('.Xdifile1.swp')
2935 call delete('.Xdifile2.swp')
2936 call delete('.Xdifile3.swp')
2937 call WriteDiffFiles3(0, [], [], [])
2938 let buf = RunVimInTerminal('-d Xdifile1 Xdifile2 Xdifile3', {})
2939 call term_sendkeys(buf, "1\<c-w>w:set autoread\<CR>")
2940 call term_sendkeys(buf, "2\<c-w>w:set autoread\<CR>")
2941 call term_sendkeys(buf, "3\<c-w>w:set autoread\<CR>")
2942 call term_sendkeys(buf, ":set diffopt+=linematch:30\<CR>")
2943 call WriteDiffFiles3(buf,
2944 \ ["",
2945 \ " common line",
2946 \ " AAA",
2947 \ " AAA",
2948 \ " AAA"],
2949 \ ["",
2950 \ " common line",
2951 \ " <<<<<<< HEAD",
2952 \ " AAA",
2953 \ " AAA",
2954 \ " AAA",
2955 \ " =======",
2956 \ " BBB",
2957 \ " BBB",
2958 \ " BBB",
2959 \ " >>>>>>> branch1"],
2960 \ ["",
2961 \ " common line",
2962 \ " BBB",
2963 \ " BBB",
2964 \ " BBB"])
2965 call VerifyScreenDump(buf, 'Test_linematch_3diffs1', {})
Jonathonca307ef2025-01-17 13:37:35 +01002966 " clean up
2967 call StopVimInTerminal(buf)
2968endfunc
Jonathon7c7a4e62025-01-12 09:58:00 +01002969
Jonathonca307ef2025-01-17 13:37:35 +01002970" this used to access invalid memory
2971func Test_linematch_3diffs_sanity_check()
2972 CheckScreendump
2973 call delete('.Xfile_linematch1.swp')
2974 call delete('.Xfile_linematch2.swp')
2975 call delete('.Xfile_linematch3.swp')
2976 let lines =<< trim END
2977 set diffopt+=linematch:60
2978 call feedkeys("Aq\<esc>")
2979 call feedkeys("GAklm\<esc>")
2980 call feedkeys("o")
2981 END
2982 call writefile(lines, 'Xlinematch_3diffs.vim', 'D')
2983 call writefile(['abcd', 'def', 'hij'], 'Xfile_linematch1', 'D')
2984 call writefile(['defq', 'hijk', 'nopq'], 'Xfile_linematch2', 'D')
2985 call writefile(['hijklm', 'nopqr', 'stuv'], 'Xfile_linematch3', 'D')
2986 call WriteDiffFiles3(0, [], [], [])
2987 let buf = RunVimInTerminal('-d -S Xlinematch_3diffs.vim Xfile_linematch1 Xfile_linematch2 Xfile_linematch3', {})
2988 call VerifyScreenDump(buf, 'Test_linematch_3diffs2', {})
2989
2990 " clean up
2991 call StopVimInTerminal(buf)
Jonathon7c7a4e62025-01-12 09:58:00 +01002992endfunc
Bram Moolenaar8dfcce32020-03-18 19:32:26 +01002993" vim: shiftwidth=2 sts=2 expandtab