blob: 461b28f69724c4c366a4a82745893eb7bd61d904 [file] [log] [blame]
Bram Moolenaar170b10b2016-07-29 16:15:27 +02001" Tests for the undo tree.
2" Since this script is sourced we need to explicitly break changes up in
3" undo-able pieces. Do that by setting 'undolevels'.
4" Also tests :earlier and :later.
5
Bram Moolenaar3f8f8272022-12-08 21:49:35 +00006source check.vim
7source screendump.vim
8
Bram Moolenaar170b10b2016-07-29 16:15:27 +02009func Test_undotree()
Bram Moolenaar80eaddd2017-11-11 23:37:08 +010010 new
11
12 normal! Aabc
Bram Moolenaar170b10b2016-07-29 16:15:27 +020013 set ul=100
Bram Moolenaar170b10b2016-07-29 16:15:27 +020014 let d = undotree()
Bram Moolenaar80eaddd2017-11-11 23:37:08 +010015 call assert_equal(1, d.seq_last)
16 call assert_equal(1, d.seq_cur)
17 call assert_equal(0, d.save_last)
18 call assert_equal(0, d.save_cur)
19 call assert_equal(1, len(d.entries))
20 call assert_equal(1, d.entries[0].newhead)
21 call assert_equal(1, d.entries[0].seq)
22 call assert_true(d.entries[0].time <= d.time_cur)
23
24 normal! Adef
25 set ul=100
26 let d = undotree()
27 call assert_equal(2, d.seq_last)
28 call assert_equal(2, d.seq_cur)
29 call assert_equal(0, d.save_last)
30 call assert_equal(0, d.save_cur)
31 call assert_equal(2, len(d.entries))
32 call assert_equal(1, d.entries[0].seq)
33 call assert_equal(1, d.entries[1].newhead)
34 call assert_equal(2, d.entries[1].seq)
35 call assert_true(d.entries[1].time <= d.time_cur)
36
37 undo
38 set ul=100
39 let d = undotree()
40 call assert_equal(2, d.seq_last)
41 call assert_equal(1, d.seq_cur)
42 call assert_equal(0, d.save_last)
43 call assert_equal(0, d.save_cur)
44 call assert_equal(2, len(d.entries))
45 call assert_equal(1, d.entries[0].seq)
46 call assert_equal(1, d.entries[1].curhead)
47 call assert_equal(1, d.entries[1].newhead)
48 call assert_equal(2, d.entries[1].seq)
49 call assert_true(d.entries[1].time == d.time_cur)
50
51 normal! Aghi
52 set ul=100
53 let d = undotree()
54 call assert_equal(3, d.seq_last)
55 call assert_equal(3, d.seq_cur)
56 call assert_equal(0, d.save_last)
57 call assert_equal(0, d.save_cur)
58 call assert_equal(2, len(d.entries))
59 call assert_equal(1, d.entries[0].seq)
60 call assert_equal(2, d.entries[1].alt[0].seq)
61 call assert_equal(1, d.entries[1].newhead)
62 call assert_equal(3, d.entries[1].seq)
63 call assert_true(d.entries[1].time <= d.time_cur)
64
65 undo
66 set ul=100
67 let d = undotree()
68 call assert_equal(3, d.seq_last)
69 call assert_equal(1, d.seq_cur)
70 call assert_equal(0, d.save_last)
71 call assert_equal(0, d.save_cur)
72 call assert_equal(2, len(d.entries))
73 call assert_equal(1, d.entries[0].seq)
74 call assert_equal(2, d.entries[1].alt[0].seq)
75 call assert_equal(1, d.entries[1].curhead)
76 call assert_equal(1, d.entries[1].newhead)
77 call assert_equal(3, d.entries[1].seq)
78 call assert_true(d.entries[1].time == d.time_cur)
Bram Moolenaar170b10b2016-07-29 16:15:27 +020079
80 w! Xtest
Bram Moolenaar80eaddd2017-11-11 23:37:08 +010081 let d = undotree()
82 call assert_equal(1, d.save_cur)
83 call assert_equal(1, d.save_last)
Bram Moolenaar170b10b2016-07-29 16:15:27 +020084 call delete('Xtest')
Bram Moolenaar80eaddd2017-11-11 23:37:08 +010085 bwipe! Xtest
Bram Moolenaar170b10b2016-07-29 16:15:27 +020086endfunc
87
88func FillBuffer()
89 for i in range(1,13)
90 put=i
Bram Moolenaare5fa1112018-05-26 18:46:30 +020091 " Set 'undolevels' to split undo.
Bram Moolenaar170b10b2016-07-29 16:15:27 +020092 exe "setg ul=" . &g:ul
93 endfor
94endfunc
95
Devin J. Pohly5fee1112023-04-23 20:26:59 -050096func Test_undotree_bufnr()
97 new
98 let buf1 = bufnr()
99
100 normal! Aabc
101 set ul=100
102
103 " Save undo tree without bufnr as ground truth for buffer 1
104 let d1 = undotree()
105
106 new
107 let buf2 = bufnr()
108
109 normal! Adef
110 set ul=100
111
112 normal! Aghi
113 set ul=100
114
115 " Save undo tree without bufnr as ground truth for buffer 2
116 let d2 = undotree()
117
118 " Check undotree() with bufnr argument
119 let d = undotree(buf1)
120 call assert_equal(d1, d)
121 call assert_notequal(d2, d)
122
123 let d = undotree(buf2)
124 call assert_notequal(d1, d)
125 call assert_equal(d2, d)
126
127 " Switch buffers and check again
128 wincmd p
129
130 let d = undotree(buf1)
131 call assert_equal(d1, d)
132
133 let d = undotree(buf2)
134 call assert_notequal(d1, d)
135 call assert_equal(d2, d)
136
137 " Drop created windows
138 set ul&
139 new
140 only!
141endfunc
142
Bram Moolenaar170b10b2016-07-29 16:15:27 +0200143func Test_global_local_undolevels()
144 new one
145 set undolevels=5
146 call FillBuffer()
147 " will only undo the last 5 changes, end up with 13 - (5 + 1) = 7 lines
148 earlier 10
149 call assert_equal(5, &g:undolevels)
150 call assert_equal(-123456, &l:undolevels)
151 call assert_equal('7', getline('$'))
152
153 new two
154 setlocal undolevels=2
155 call FillBuffer()
156 " will only undo the last 2 changes, end up with 13 - (2 + 1) = 10 lines
157 earlier 10
158 call assert_equal(5, &g:undolevels)
159 call assert_equal(2, &l:undolevels)
160 call assert_equal('10', getline('$'))
161
162 setlocal ul=10
163 call assert_equal(5, &g:undolevels)
164 call assert_equal(10, &l:undolevels)
165
166 " Setting local value in "two" must not change local value in "one"
167 wincmd p
168 call assert_equal(5, &g:undolevels)
169 call assert_equal(-123456, &l:undolevels)
170
171 new three
172 setglobal ul=50
173 call assert_equal(50, &g:undolevels)
174 call assert_equal(-123456, &l:undolevels)
175
Bram Moolenaar1363a302020-04-12 13:50:26 +0200176 " Resetting the local 'undolevels' value to use the global value
177 setlocal undolevels=5
178 setlocal undolevels<
179 call assert_equal(-123456, &l:undolevels)
180
Bram Moolenaar170b10b2016-07-29 16:15:27 +0200181 " Drop created windows
182 set ul&
183 new
184 only!
185endfunc
186
187func BackOne(expected)
188 call feedkeys('g-', 'xt')
189 call assert_equal(a:expected, getline(1))
190endfunc
191
192func Test_undo_del_chars()
193 " Setup a buffer without creating undo entries
194 new
195 set ul=-1
196 call setline(1, ['123-456'])
197 set ul=100
198 1
199 call test_settime(100)
200
201 " Delete three characters and undo with g-
202 call feedkeys('x', 'xt')
203 call feedkeys('x', 'xt')
204 call feedkeys('x', 'xt')
205 call assert_equal('-456', getline(1))
206 call BackOne('3-456')
207 call BackOne('23-456')
208 call BackOne('123-456')
209 call assert_fails("BackOne('123-456')")
210
211 :" Delete three other characters and go back in time with g-
212 call feedkeys('$x', 'xt')
213 call feedkeys('x', 'xt')
214 call feedkeys('x', 'xt')
215 call assert_equal('123-', getline(1))
216 call test_settime(101)
217
218 call BackOne('123-4')
219 call BackOne('123-45')
220 " skips '123-456' because it's older
221 call BackOne('-456')
222 call BackOne('3-456')
223 call BackOne('23-456')
224 call BackOne('123-456')
225 call assert_fails("BackOne('123-456')")
226 normal 10g+
227 call assert_equal('123-', getline(1))
228
229 :" Jump two seconds and go some seconds forward and backward
230 call test_settime(103)
231 call feedkeys("Aa\<Esc>", 'xt')
232 call feedkeys("Ab\<Esc>", 'xt')
233 call feedkeys("Ac\<Esc>", 'xt')
234 call assert_equal('123-abc', getline(1))
235 earlier 1s
236 call assert_equal('123-', getline(1))
237 earlier 3s
238 call assert_equal('123-456', getline(1))
239 later 1s
240 call assert_equal('123-', getline(1))
241 later 1h
242 call assert_equal('123-abc', getline(1))
243
244 close!
245endfunc
246
Bram Moolenaarc628fdc2016-08-31 20:33:27 +0200247func Test_undolist()
248 new
249 set ul=100
250
Bram Moolenaare5fa1112018-05-26 18:46:30 +0200251 let a = execute('undolist')
Bram Moolenaarc628fdc2016-08-31 20:33:27 +0200252 call assert_equal("\nNothing to undo", a)
253
254 " 1 leaf (2 changes).
255 call feedkeys('achange1', 'xt')
256 call feedkeys('achange2', 'xt')
Bram Moolenaare5fa1112018-05-26 18:46:30 +0200257 let a = execute('undolist')
Bram Moolenaarc628fdc2016-08-31 20:33:27 +0200258 call assert_match("^\nnumber changes when *saved\n *2 *2 .*$", a)
259
260 " 2 leaves.
261 call feedkeys('u', 'xt')
262 call feedkeys('achange3\<Esc>', 'xt')
Bram Moolenaare5fa1112018-05-26 18:46:30 +0200263 let a = execute('undolist')
Bram Moolenaarc628fdc2016-08-31 20:33:27 +0200264 call assert_match("^\nnumber changes when *saved\n *2 *2 *.*\n *3 *2 .*$", a)
265 close!
266endfunc
267
268func Test_U_command()
269 new
270 set ul=100
271 call feedkeys("achange1\<Esc>", 'xt')
272 call feedkeys("achange2\<Esc>", 'xt')
273 norm! U
274 call assert_equal('', getline(1))
275 norm! U
276 call assert_equal('change1change2', getline(1))
277 close!
278endfunc
279
Bram Moolenaar170b10b2016-07-29 16:15:27 +0200280func Test_undojoin()
281 new
282 call feedkeys("Goaaaa\<Esc>", 'xt')
283 call feedkeys("obbbb\<Esc>", 'xt')
284 call assert_equal(['aaaa', 'bbbb'], getline(2, '$'))
285 call feedkeys("u", 'xt')
286 call assert_equal(['aaaa'], getline(2, '$'))
287 call feedkeys("obbbb\<Esc>", 'xt')
288 undojoin
289 " Note: next change must not be as if typed
290 call feedkeys("occcc\<Esc>", 'x')
291 call assert_equal(['aaaa', 'bbbb', 'cccc'], getline(2, '$'))
292 call feedkeys("u", 'xt')
293 call assert_equal(['aaaa'], getline(2, '$'))
Bram Moolenaar5e4e1b12017-01-17 22:09:45 +0100294 bwipe!
295endfunc
296
297func Test_undojoin_redo()
298 new
299 call setline(1, ['first line', 'second line'])
300 call feedkeys("ixx\<Esc>", 'xt')
301 call feedkeys(":undojoin | redo\<CR>", 'xt')
302 call assert_equal('xxfirst line', getline(1))
303 call assert_equal('second line', getline(2))
304 bwipe!
Bram Moolenaar170b10b2016-07-29 16:15:27 +0200305endfunc
306
Bram Moolenaar559b9c62019-12-15 18:09:19 +0100307" undojoin not allowed after undo
308func Test_undojoin_after_undo()
309 new
310 call feedkeys("ixx\<Esc>u", 'xt')
311 call assert_fails(':undojoin', 'E790:')
312 bwipe!
313endfunc
314
315" undojoin is a noop when no change yet, or when 'undolevels' is negative
316func Test_undojoin_noop()
317 new
318 call feedkeys(":undojoin\<CR>", 'xt')
319 call assert_equal([''], getline(1, '$'))
320 setlocal undolevels=-1
321 call feedkeys("ixx\<Esc>u", 'xt')
322 call feedkeys(":undojoin\<CR>", 'xt')
323 call assert_equal(['xx'], getline(1, '$'))
324 bwipe!
325endfunc
326
Bram Moolenaar170b10b2016-07-29 16:15:27 +0200327func Test_undo_write()
Bram Moolenaar5842a742017-11-04 22:36:53 +0100328 call delete('Xtest')
Bram Moolenaar170b10b2016-07-29 16:15:27 +0200329 split Xtest
330 call feedkeys("ione one one\<Esc>", 'xt')
331 w!
332 call feedkeys("otwo\<Esc>", 'xt')
333 call feedkeys("otwo\<Esc>", 'xt')
334 w
335 call feedkeys("othree\<Esc>", 'xt')
336 call assert_equal(['one one one', 'two', 'two', 'three'], getline(1, '$'))
337 earlier 1f
338 call assert_equal(['one one one', 'two', 'two'], getline(1, '$'))
339 earlier 1f
340 call assert_equal(['one one one'], getline(1, '$'))
341 earlier 1f
342 call assert_equal([''], getline(1, '$'))
343 later 1f
344 call assert_equal(['one one one'], getline(1, '$'))
345 later 1f
346 call assert_equal(['one one one', 'two', 'two'], getline(1, '$'))
347 later 1f
348 call assert_equal(['one one one', 'two', 'two', 'three'], getline(1, '$'))
349
350 close!
351 call delete('Xtest')
352 bwipe! Xtest
Bram Moolenaar9f6277b2020-02-11 22:04:02 +0100353
354 call assert_fails('earlier xyz', 'E475:')
Bram Moolenaar170b10b2016-07-29 16:15:27 +0200355endfunc
356
357func Test_insert_expr()
358 new
359 " calling setline() triggers undo sync
360 call feedkeys("oa\<Esc>", 'xt')
361 call feedkeys("ob\<Esc>", 'xt')
362 set ul=100
363 call feedkeys("o1\<Esc>a2\<C-R>=setline('.','1234')\<CR>\<CR>\<Esc>", 'x')
364 call assert_equal(['a', 'b', '120', '34'], getline(2, '$'))
365 call feedkeys("u", 'x')
366 call assert_equal(['a', 'b', '12'], getline(2, '$'))
367 call feedkeys("u", 'x')
368 call assert_equal(['a', 'b'], getline(2, '$'))
369
370 call feedkeys("oc\<Esc>", 'xt')
371 set ul=100
372 call feedkeys("o1\<Esc>a2\<C-R>=setline('.','1234')\<CR>\<CR>\<Esc>", 'x')
373 call assert_equal(['a', 'b', 'c', '120', '34'], getline(2, '$'))
374 call feedkeys("u", 'x')
375 call assert_equal(['a', 'b', 'c', '12'], getline(2, '$'))
376
377 call feedkeys("od\<Esc>", 'xt')
378 set ul=100
379 call feedkeys("o1\<Esc>a2\<C-R>=string(123)\<CR>\<Esc>", 'x')
380 call assert_equal(['a', 'b', 'c', '12', 'd', '12123'], getline(2, '$'))
381 call feedkeys("u", 'x')
382 call assert_equal(['a', 'b', 'c', '12', 'd'], getline(2, '$'))
383
384 close!
385endfunc
Bram Moolenaarcbd4de42017-01-07 16:14:57 +0100386
387func Test_undofile_earlier()
K.Takata0500e872022-09-08 12:28:02 +0100388 if has('win32')
389 " FIXME: This test is flaky on MS-Windows.
390 let g:test_is_flaky = 1
391 endif
392
Bram Moolenaarcbd4de42017-01-07 16:14:57 +0100393 " Issue #1254
394 " create undofile with timestamps older than Vim startup time.
395 let t0 = localtime() - 43200
396 call test_settime(t0)
Bram Moolenaarcce293f2022-08-15 17:28:27 +0100397 new XfileEarlier
Bram Moolenaarcbd4de42017-01-07 16:14:57 +0100398 call feedkeys("ione\<Esc>", 'xt')
399 set ul=100
400 call test_settime(t0 + 1)
401 call feedkeys("otwo\<Esc>", 'xt')
402 set ul=100
403 call test_settime(t0 + 2)
404 call feedkeys("othree\<Esc>", 'xt')
405 set ul=100
406 w
407 wundo Xundofile
408 bwipe!
409 " restore normal timestamps.
410 call test_settime(0)
Bram Moolenaarcce293f2022-08-15 17:28:27 +0100411 new XfileEarlier
Bram Moolenaarcbd4de42017-01-07 16:14:57 +0100412 rundo Xundofile
413 earlier 1d
414 call assert_equal('', getline(1))
415 bwipe!
Bram Moolenaarcce293f2022-08-15 17:28:27 +0100416 call delete('XfileEarlier')
Bram Moolenaarcbd4de42017-01-07 16:14:57 +0100417 call delete('Xundofile')
418endfunc
Bram Moolenaar15993ce2017-10-26 20:21:44 +0200419
Bram Moolenaar559b9c62019-12-15 18:09:19 +0100420func Test_wundo_errors()
421 new
422 call setline(1, 'hello')
423 call assert_fails('wundo! Xdoesnotexist/Xundofile', 'E828:')
424 bwipe!
425endfunc
426
427" Check that reading a truncated undo file doesn't hang.
Bram Moolenaarfb06d762019-08-04 18:55:35 +0200428func Test_undofile_truncated()
429 new
430 call setline(1, 'hello')
431 set ul=100
432 wundo Xundofile
433 let contents = readfile('Xundofile', 'B')
434
435 " try several sizes
436 for size in range(20, 500, 33)
Bram Moolenaar5b148ef2022-10-15 21:35:56 +0100437 call writefile(contents[0:size], 'Xundofile', 'D')
Bram Moolenaarfb06d762019-08-04 18:55:35 +0200438 call assert_fails('rundo Xundofile', 'E825:')
439 endfor
440
441 bwipe!
Bram Moolenaarfb06d762019-08-04 18:55:35 +0200442endfunc
443
Bram Moolenaar559b9c62019-12-15 18:09:19 +0100444func Test_rundo_errors()
445 call assert_fails('rundo XfileDoesNotExist', 'E822:')
446
Bram Moolenaar5b148ef2022-10-15 21:35:56 +0100447 call writefile(['abc'], 'Xundofile', 'D')
Bram Moolenaar559b9c62019-12-15 18:09:19 +0100448 call assert_fails('rundo Xundofile', 'E823:')
Bram Moolenaar559b9c62019-12-15 18:09:19 +0100449endfunc
450
Bram Moolenaar55b419b2020-10-04 19:56:39 +0200451func Test_undofile_next()
452 set undofile
453 new Xfoo.txt
454 execute "norm ix\<c-g>uy\<c-g>uz\<Esc>"
455 write
456 bwipe
457
458 next Xfoo.txt
459 call assert_equal('xyz', getline(1))
460 silent undo
461 call assert_equal('xy', getline(1))
462 silent undo
463 call assert_equal('x', getline(1))
464 bwipe!
465
466 call delete('Xfoo.txt')
467 call delete('.Xfoo.txt.un~')
468 set undofile&
469endfunc
470
Bram Moolenaar15993ce2017-10-26 20:21:44 +0200471" Test for undo working properly when executing commands from a register.
472" Also test this in an empty buffer.
473func Test_cmd_in_reg_undo()
474 enew!
Bram Moolenaare5fa1112018-05-26 18:46:30 +0200475 let @a = "Ox\<Esc>jAy\<Esc>kdd"
Bram Moolenaar15993ce2017-10-26 20:21:44 +0200476 edit +/^$ test_undo.vim
477 normal @au
478 call assert_equal(0, &modified)
479 return
480 new
481 normal @au
482 call assert_equal(0, &modified)
483 only!
Bram Moolenaare5fa1112018-05-26 18:46:30 +0200484 let @a = ''
Bram Moolenaar15993ce2017-10-26 20:21:44 +0200485endfunc
Bram Moolenaar95dbcbe2018-01-27 21:01:34 +0100486
487" This used to cause an illegal memory access
488func Test_undo_append()
489 new
490 call feedkeys("axx\<Esc>v", 'xt')
491 undo
492 norm o
493 quit
494endfunc
Bram Moolenaarce46d932018-01-30 22:46:06 +0100495
496func Test_undo_0()
497 new
498 set ul=100
499 normal i1
500 undo
501 normal i2
502 undo
503 normal i3
504
505 undo 0
506 let d = undotree()
507 call assert_equal('', getline(1))
508 call assert_equal(0, d.seq_cur)
509
510 redo
511 let d = undotree()
512 call assert_equal('3', getline(1))
513 call assert_equal(3, d.seq_cur)
514
515 undo 2
516 undo 0
517 let d = undotree()
518 call assert_equal('', getline(1))
519 call assert_equal(0, d.seq_cur)
520
521 redo
522 let d = undotree()
523 call assert_equal('2', getline(1))
524 call assert_equal(2, d.seq_cur)
525
526 undo 1
527 undo 0
528 let d = undotree()
529 call assert_equal('', getline(1))
530 call assert_equal(0, d.seq_cur)
531
532 redo
533 let d = undotree()
534 call assert_equal('1', getline(1))
535 call assert_equal(1, d.seq_cur)
536
537 bwipe!
538endfunc
Bram Moolenaarf12519d2018-02-06 22:52:49 +0100539
Bram Moolenaar559b9c62019-12-15 18:09:19 +0100540" undo or redo are noop if there is nothing to undo or redo
541func Test_undo_redo_noop()
542 new
543 call assert_fails('undo 2', 'E830:')
544
545 message clear
546 undo
547 let messages = split(execute('message'), "\n")
548 call assert_equal('Already at oldest change', messages[-1])
549
550 message clear
551 redo
552 let messages = split(execute('message'), "\n")
553 call assert_equal('Already at newest change', messages[-1])
554
555 bwipe!
556endfunc
557
Bram Moolenaarf12519d2018-02-06 22:52:49 +0100558func Test_redo_empty_line()
559 new
560 exe "norm\x16r\x160"
561 exe "norm."
562 bwipe!
563endfunc
Bram Moolenaare5fa1112018-05-26 18:46:30 +0200564
565funct Test_undofile()
566 " Test undofile() without setting 'undodir'.
567 if has('persistent_undo')
568 call assert_equal(fnamemodify('.Xundofoo.un~', ':p'), undofile('Xundofoo'))
569 else
570 call assert_equal('', undofile('Xundofoo'))
571 endif
572 call assert_equal('', undofile(''))
573
574 " Test undofile() with 'undodir' set to to an existing directory.
575 call mkdir('Xundodir')
576 set undodir=Xundodir
577 let cwd = getcwd()
578 if has('win32')
579 " Replace windows drive such as C:... into C%...
Bram Moolenaar56242f22018-12-14 15:48:48 +0100580 let cwd = substitute(cwd, '^\([a-zA-Z]\):', '\1%', 'g')
Bram Moolenaare5fa1112018-05-26 18:46:30 +0200581 endif
582 let cwd = substitute(cwd . '/Xundofoo', '/', '%', 'g')
583 if has('persistent_undo')
584 call assert_equal('Xundodir/' . cwd, undofile('Xundofoo'))
585 else
586 call assert_equal('', undofile('Xundofoo'))
587 endif
588 call assert_equal('', undofile(''))
589 call delete('Xundodir', 'd')
590
591 " Test undofile() with 'undodir' set to a non-existing directory.
Bram Moolenaarf92e58c2019-09-08 21:51:41 +0200592 call assert_equal('', 'Xundofoo'->undofile())
Bram Moolenaare5fa1112018-05-26 18:46:30 +0200593
Bram Moolenaar077ff432019-10-28 00:42:21 +0100594 if !has('win32') && isdirectory('/tmp')
Bram Moolenaare9ebc9a2019-05-19 15:27:14 +0200595 set undodir=/tmp
Bram Moolenaar2b39d802019-05-19 16:38:56 +0200596 if has('osx')
597 call assert_equal('/tmp/%private%tmp%file', undofile('///tmp/file'))
598 else
599 call assert_equal('/tmp/%tmp%file', undofile('///tmp/file'))
600 endif
Bram Moolenaare9ebc9a2019-05-19 15:27:14 +0200601 endif
602
Bram Moolenaare5fa1112018-05-26 18:46:30 +0200603 set undodir&
604endfunc
Bram Moolenaar3e2d1c82019-12-14 20:35:01 +0100605
606" Tests for the undo file
607" Explicitly break changes up in undo-able pieces by setting 'undolevels'.
608func Test_undofile_2()
609 set undolevels=100 undofile
610 edit Xtestfile
611 call append(0, 'this is one line')
612 call cursor(1, 1)
613
614 " first a simple one-line change.
615 set undolevels=100
616 s/one/ONE/
617 set undolevels=100
618 write
619 bwipe!
620 edit Xtestfile
621 undo
622 call assert_equal('this is one line', getline(1))
623
624 " change in original file fails check
625 set noundofile
626 edit! Xtestfile
627 s/line/Line/
628 write
629 set undofile
630 bwipe!
631 edit Xtestfile
632 undo
633 call assert_equal('this is ONE Line', getline(1))
634
635 " add 10 lines, delete 6 lines, undo 3
636 set undofile
Bram Moolenaarb8bd2e62021-08-21 17:13:14 +0200637 call setbufline('%', 1, ['one', 'two', 'three', 'four', 'five', 'six',
Bram Moolenaar3e2d1c82019-12-14 20:35:01 +0100638 \ 'seven', 'eight', 'nine', 'ten'])
639 set undolevels=100
640 normal 3Gdd
641 set undolevels=100
642 normal dd
643 set undolevels=100
644 normal dd
645 set undolevels=100
646 normal dd
647 set undolevels=100
648 normal dd
649 set undolevels=100
650 normal dd
651 set undolevels=100
652 write
653 bwipe!
654 edit Xtestfile
655 normal uuu
656 call assert_equal(['one', 'two', 'six', 'seven', 'eight', 'nine', 'ten'],
657 \ getline(1, '$'))
658
659 " Test that reading the undofiles when setting undofile works
660 set noundofile undolevels=0
661 exe "normal i\n"
662 undo
663 edit! Xtestfile
664 set undofile undolevels=100
665 normal uuuuuu
666 call assert_equal(['one', 'two', 'three', 'four', 'five', 'six', 'seven',
667 \ 'eight', 'nine', 'ten'], getline(1, '$'))
668
669 bwipe!
670 call delete('Xtestfile')
671 let ufile = has('vms') ? '_un_Xtestfile' : '.Xtestfile.un~'
672 call delete(ufile)
673 set undofile& undolevels&
674endfunc
675
676" Test 'undofile' using a file encrypted with 'zip' crypt method
677func Test_undofile_cryptmethod_zip()
678 edit Xtestfile
679 set undofile cryptmethod=zip
680 call append(0, ['monday', 'tuesday', 'wednesday', 'thursday', 'friday'])
681 call cursor(5, 1)
682
683 set undolevels=100
684 normal kkkdd
685 set undolevels=100
686 normal dd
687 set undolevels=100
688 normal dd
689 set undolevels=100
690 " encrypt the file using key 'foobar'
691 call feedkeys("foobar\nfoobar\n")
692 X
693 write!
694 bwipe!
695
696 call feedkeys("foobar\n")
697 edit Xtestfile
698 set key=
699 normal uu
700 call assert_equal(['monday', 'wednesday', 'thursday', 'friday', ''],
701 \ getline(1, '$'))
702
703 bwipe!
704 call delete('Xtestfile')
705 let ufile = has('vms') ? '_un_Xtestfile' : '.Xtestfile.un~'
706 call delete(ufile)
707 set undofile& undolevels& cryptmethod&
708endfunc
709
710" Test 'undofile' using a file encrypted with 'blowfish' crypt method
711func Test_undofile_cryptmethod_blowfish()
712 edit Xtestfile
713 set undofile cryptmethod=blowfish
714 call append(0, ['jan', 'feb', 'mar', 'apr', 'jun'])
715 call cursor(5, 1)
716
717 set undolevels=100
718 exe 'normal kk0ifoo '
719 set undolevels=100
720 normal dd
721 set undolevels=100
722 exe 'normal ibar '
723 set undolevels=100
724 " encrypt the file using key 'foobar'
725 call feedkeys("foobar\nfoobar\n")
726 X
727 write!
728 bwipe!
729
730 call feedkeys("foobar\n")
731 edit Xtestfile
732 set key=
733 call search('bar')
734 call assert_equal('bar apr', getline('.'))
735 undo
736 call assert_equal('apr', getline('.'))
737 undo
738 call assert_equal('foo mar', getline('.'))
739 undo
740 call assert_equal('mar', getline('.'))
741
742 bwipe!
743 call delete('Xtestfile')
744 let ufile = has('vms') ? '_un_Xtestfile' : '.Xtestfile.un~'
745 call delete(ufile)
746 set undofile& undolevels& cryptmethod&
747endfunc
748
749" Test 'undofile' using a file encrypted with 'blowfish2' crypt method
750func Test_undofile_cryptmethod_blowfish2()
751 edit Xtestfile
752 set undofile cryptmethod=blowfish2
753 call append(0, ['jan', 'feb', 'mar', 'apr', 'jun'])
754 call cursor(5, 1)
755
756 set undolevels=100
757 exe 'normal kk0ifoo '
758 set undolevels=100
759 normal dd
760 set undolevels=100
761 exe 'normal ibar '
762 set undolevels=100
763 " encrypt the file using key 'foo2bar'
764 call feedkeys("foo2bar\nfoo2bar\n")
765 X
766 write!
767 bwipe!
768
769 call feedkeys("foo2bar\n")
770 edit Xtestfile
771 set key=
772 call search('bar')
773 call assert_equal('bar apr', getline('.'))
774 normal u
775 call assert_equal('apr', getline('.'))
776 normal u
777 call assert_equal('foo mar', getline('.'))
778 normal u
779 call assert_equal('mar', getline('.'))
780
781 bwipe!
782 call delete('Xtestfile')
783 let ufile = has('vms') ? '_un_Xtestfile' : '.Xtestfile.un~'
784 call delete(ufile)
785 set undofile& undolevels& cryptmethod&
786endfunc
787
Bram Moolenaarf4fcedc2021-03-15 18:36:20 +0100788" Test for redoing with incrementing numbered registers
789func Test_redo_repeat_numbered_register()
790 new
791 for [i, v] in [[1, 'one'], [2, 'two'], [3, 'three'],
792 \ [4, 'four'], [5, 'five'], [6, 'six'],
793 \ [7, 'seven'], [8, 'eight'], [9, 'nine']]
794 exe 'let @' .. i .. '="' .. v .. '\n"'
795 endfor
796 call feedkeys('"1p.........', 'xt')
797 call assert_equal(['', 'one', 'two', 'three', 'four', 'five', 'six',
798 \ 'seven', 'eight', 'nine', 'nine'], getline(1, '$'))
799 bwipe!
800endfunc
801
Bram Moolenaar1f448d92021-03-22 19:37:06 +0100802" Test for redo in insert mode using CTRL-O with multibyte characters
803func Test_redo_multibyte_in_insert_mode()
804 new
805 call feedkeys("a\<C-K>ft", 'xt')
806 call feedkeys("uiHe\<C-O>.llo", 'xt')
807 call assert_equal("He\ufb05llo", getline(1))
808 bwipe!
809endfunc
810
LemonBoy82444ce2022-05-12 15:39:31 +0100811func Test_undo_mark()
812 new
813 " The undo is applied to the only line.
814 call setline(1, 'hello')
815 call feedkeys("ggyiw$p", 'xt')
816 undo
817 call assert_equal([0, 1, 1, 0], getpos("'["))
818 call assert_equal([0, 1, 1, 0], getpos("']"))
819 " The undo removes the last line.
820 call feedkeys("Goaaaa\<Esc>", 'xt')
821 call feedkeys("obbbb\<Esc>", 'xt')
822 undo
823 call assert_equal([0, 2, 1, 0], getpos("'["))
824 call assert_equal([0, 2, 1, 0], getpos("']"))
825 bwipe!
826endfunc
827
Bram Moolenaar3f8f8272022-12-08 21:49:35 +0000828func Test_undo_after_write()
829 " use a terminal to make undo work like when text is typed
830 CheckRunVimInTerminal
831
832 let lines =<< trim END
833 edit Xtestfile.txt
834 set undolevels=100 undofile
835 imap . <Cmd>write<CR>
836 write
837 END
838 call writefile(lines, 'Xtest_undo_after_write', 'D')
839 let buf = RunVimInTerminal('-S Xtest_undo_after_write', #{rows: 6})
840
841 call term_sendkeys(buf, "Otest.\<CR>boo!!!\<Esc>")
842 sleep 100m
843 call term_sendkeys(buf, "u")
844 call VerifyScreenDump(buf, 'Test_undo_after_write_1', {})
845
846 call term_sendkeys(buf, "u")
847 call VerifyScreenDump(buf, 'Test_undo_after_write_2', {})
848
849 call StopVimInTerminal(buf)
850 call delete('Xtestfile.txt')
851endfunc
852
853
Bram Moolenaar3e2d1c82019-12-14 20:35:01 +0100854" vim: shiftwidth=2 sts=2 expandtab