blob: 2529e21085a3a56b1f44201707bb1b64f78566bd [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
96func Test_global_local_undolevels()
97 new one
98 set undolevels=5
99 call FillBuffer()
100 " will only undo the last 5 changes, end up with 13 - (5 + 1) = 7 lines
101 earlier 10
102 call assert_equal(5, &g:undolevels)
103 call assert_equal(-123456, &l:undolevels)
104 call assert_equal('7', getline('$'))
105
106 new two
107 setlocal undolevels=2
108 call FillBuffer()
109 " will only undo the last 2 changes, end up with 13 - (2 + 1) = 10 lines
110 earlier 10
111 call assert_equal(5, &g:undolevels)
112 call assert_equal(2, &l:undolevels)
113 call assert_equal('10', getline('$'))
114
115 setlocal ul=10
116 call assert_equal(5, &g:undolevels)
117 call assert_equal(10, &l:undolevels)
118
119 " Setting local value in "two" must not change local value in "one"
120 wincmd p
121 call assert_equal(5, &g:undolevels)
122 call assert_equal(-123456, &l:undolevels)
123
124 new three
125 setglobal ul=50
126 call assert_equal(50, &g:undolevels)
127 call assert_equal(-123456, &l:undolevels)
128
Bram Moolenaar1363a302020-04-12 13:50:26 +0200129 " Resetting the local 'undolevels' value to use the global value
130 setlocal undolevels=5
131 setlocal undolevels<
132 call assert_equal(-123456, &l:undolevels)
133
Bram Moolenaar170b10b2016-07-29 16:15:27 +0200134 " Drop created windows
135 set ul&
136 new
137 only!
138endfunc
139
140func BackOne(expected)
141 call feedkeys('g-', 'xt')
142 call assert_equal(a:expected, getline(1))
143endfunc
144
145func Test_undo_del_chars()
146 " Setup a buffer without creating undo entries
147 new
148 set ul=-1
149 call setline(1, ['123-456'])
150 set ul=100
151 1
152 call test_settime(100)
153
154 " Delete three characters and undo with g-
155 call feedkeys('x', 'xt')
156 call feedkeys('x', 'xt')
157 call feedkeys('x', 'xt')
158 call assert_equal('-456', getline(1))
159 call BackOne('3-456')
160 call BackOne('23-456')
161 call BackOne('123-456')
162 call assert_fails("BackOne('123-456')")
163
164 :" Delete three other characters and go back in time with g-
165 call feedkeys('$x', 'xt')
166 call feedkeys('x', 'xt')
167 call feedkeys('x', 'xt')
168 call assert_equal('123-', getline(1))
169 call test_settime(101)
170
171 call BackOne('123-4')
172 call BackOne('123-45')
173 " skips '123-456' because it's older
174 call BackOne('-456')
175 call BackOne('3-456')
176 call BackOne('23-456')
177 call BackOne('123-456')
178 call assert_fails("BackOne('123-456')")
179 normal 10g+
180 call assert_equal('123-', getline(1))
181
182 :" Jump two seconds and go some seconds forward and backward
183 call test_settime(103)
184 call feedkeys("Aa\<Esc>", 'xt')
185 call feedkeys("Ab\<Esc>", 'xt')
186 call feedkeys("Ac\<Esc>", 'xt')
187 call assert_equal('123-abc', getline(1))
188 earlier 1s
189 call assert_equal('123-', getline(1))
190 earlier 3s
191 call assert_equal('123-456', getline(1))
192 later 1s
193 call assert_equal('123-', getline(1))
194 later 1h
195 call assert_equal('123-abc', getline(1))
196
197 close!
198endfunc
199
Bram Moolenaarc628fdc2016-08-31 20:33:27 +0200200func Test_undolist()
201 new
202 set ul=100
203
Bram Moolenaare5fa1112018-05-26 18:46:30 +0200204 let a = execute('undolist')
Bram Moolenaarc628fdc2016-08-31 20:33:27 +0200205 call assert_equal("\nNothing to undo", a)
206
207 " 1 leaf (2 changes).
208 call feedkeys('achange1', 'xt')
209 call feedkeys('achange2', 'xt')
Bram Moolenaare5fa1112018-05-26 18:46:30 +0200210 let a = execute('undolist')
Bram Moolenaarc628fdc2016-08-31 20:33:27 +0200211 call assert_match("^\nnumber changes when *saved\n *2 *2 .*$", a)
212
213 " 2 leaves.
214 call feedkeys('u', 'xt')
215 call feedkeys('achange3\<Esc>', 'xt')
Bram Moolenaare5fa1112018-05-26 18:46:30 +0200216 let a = execute('undolist')
Bram Moolenaarc628fdc2016-08-31 20:33:27 +0200217 call assert_match("^\nnumber changes when *saved\n *2 *2 *.*\n *3 *2 .*$", a)
218 close!
219endfunc
220
221func Test_U_command()
222 new
223 set ul=100
224 call feedkeys("achange1\<Esc>", 'xt')
225 call feedkeys("achange2\<Esc>", 'xt')
226 norm! U
227 call assert_equal('', getline(1))
228 norm! U
229 call assert_equal('change1change2', getline(1))
230 close!
231endfunc
232
Bram Moolenaar170b10b2016-07-29 16:15:27 +0200233func Test_undojoin()
234 new
235 call feedkeys("Goaaaa\<Esc>", 'xt')
236 call feedkeys("obbbb\<Esc>", 'xt')
237 call assert_equal(['aaaa', 'bbbb'], getline(2, '$'))
238 call feedkeys("u", 'xt')
239 call assert_equal(['aaaa'], getline(2, '$'))
240 call feedkeys("obbbb\<Esc>", 'xt')
241 undojoin
242 " Note: next change must not be as if typed
243 call feedkeys("occcc\<Esc>", 'x')
244 call assert_equal(['aaaa', 'bbbb', 'cccc'], getline(2, '$'))
245 call feedkeys("u", 'xt')
246 call assert_equal(['aaaa'], getline(2, '$'))
Bram Moolenaar5e4e1b12017-01-17 22:09:45 +0100247 bwipe!
248endfunc
249
250func Test_undojoin_redo()
251 new
252 call setline(1, ['first line', 'second line'])
253 call feedkeys("ixx\<Esc>", 'xt')
254 call feedkeys(":undojoin | redo\<CR>", 'xt')
255 call assert_equal('xxfirst line', getline(1))
256 call assert_equal('second line', getline(2))
257 bwipe!
Bram Moolenaar170b10b2016-07-29 16:15:27 +0200258endfunc
259
Bram Moolenaar559b9c62019-12-15 18:09:19 +0100260" undojoin not allowed after undo
261func Test_undojoin_after_undo()
262 new
263 call feedkeys("ixx\<Esc>u", 'xt')
264 call assert_fails(':undojoin', 'E790:')
265 bwipe!
266endfunc
267
268" undojoin is a noop when no change yet, or when 'undolevels' is negative
269func Test_undojoin_noop()
270 new
271 call feedkeys(":undojoin\<CR>", 'xt')
272 call assert_equal([''], getline(1, '$'))
273 setlocal undolevels=-1
274 call feedkeys("ixx\<Esc>u", 'xt')
275 call feedkeys(":undojoin\<CR>", 'xt')
276 call assert_equal(['xx'], getline(1, '$'))
277 bwipe!
278endfunc
279
Bram Moolenaar170b10b2016-07-29 16:15:27 +0200280func Test_undo_write()
Bram Moolenaar5842a742017-11-04 22:36:53 +0100281 call delete('Xtest')
Bram Moolenaar170b10b2016-07-29 16:15:27 +0200282 split Xtest
283 call feedkeys("ione one one\<Esc>", 'xt')
284 w!
285 call feedkeys("otwo\<Esc>", 'xt')
286 call feedkeys("otwo\<Esc>", 'xt')
287 w
288 call feedkeys("othree\<Esc>", 'xt')
289 call assert_equal(['one one one', 'two', 'two', 'three'], getline(1, '$'))
290 earlier 1f
291 call assert_equal(['one one one', 'two', 'two'], getline(1, '$'))
292 earlier 1f
293 call assert_equal(['one one one'], getline(1, '$'))
294 earlier 1f
295 call assert_equal([''], getline(1, '$'))
296 later 1f
297 call assert_equal(['one one one'], getline(1, '$'))
298 later 1f
299 call assert_equal(['one one one', 'two', 'two'], getline(1, '$'))
300 later 1f
301 call assert_equal(['one one one', 'two', 'two', 'three'], getline(1, '$'))
302
303 close!
304 call delete('Xtest')
305 bwipe! Xtest
Bram Moolenaar9f6277b2020-02-11 22:04:02 +0100306
307 call assert_fails('earlier xyz', 'E475:')
Bram Moolenaar170b10b2016-07-29 16:15:27 +0200308endfunc
309
310func Test_insert_expr()
311 new
312 " calling setline() triggers undo sync
313 call feedkeys("oa\<Esc>", 'xt')
314 call feedkeys("ob\<Esc>", 'xt')
315 set ul=100
316 call feedkeys("o1\<Esc>a2\<C-R>=setline('.','1234')\<CR>\<CR>\<Esc>", 'x')
317 call assert_equal(['a', 'b', '120', '34'], getline(2, '$'))
318 call feedkeys("u", 'x')
319 call assert_equal(['a', 'b', '12'], getline(2, '$'))
320 call feedkeys("u", 'x')
321 call assert_equal(['a', 'b'], getline(2, '$'))
322
323 call feedkeys("oc\<Esc>", 'xt')
324 set ul=100
325 call feedkeys("o1\<Esc>a2\<C-R>=setline('.','1234')\<CR>\<CR>\<Esc>", 'x')
326 call assert_equal(['a', 'b', 'c', '120', '34'], getline(2, '$'))
327 call feedkeys("u", 'x')
328 call assert_equal(['a', 'b', 'c', '12'], getline(2, '$'))
329
330 call feedkeys("od\<Esc>", 'xt')
331 set ul=100
332 call feedkeys("o1\<Esc>a2\<C-R>=string(123)\<CR>\<Esc>", 'x')
333 call assert_equal(['a', 'b', 'c', '12', 'd', '12123'], getline(2, '$'))
334 call feedkeys("u", 'x')
335 call assert_equal(['a', 'b', 'c', '12', 'd'], getline(2, '$'))
336
337 close!
338endfunc
Bram Moolenaarcbd4de42017-01-07 16:14:57 +0100339
340func Test_undofile_earlier()
K.Takata0500e872022-09-08 12:28:02 +0100341 if has('win32')
342 " FIXME: This test is flaky on MS-Windows.
343 let g:test_is_flaky = 1
344 endif
345
Bram Moolenaarcbd4de42017-01-07 16:14:57 +0100346 " Issue #1254
347 " create undofile with timestamps older than Vim startup time.
348 let t0 = localtime() - 43200
349 call test_settime(t0)
Bram Moolenaarcce293f2022-08-15 17:28:27 +0100350 new XfileEarlier
Bram Moolenaarcbd4de42017-01-07 16:14:57 +0100351 call feedkeys("ione\<Esc>", 'xt')
352 set ul=100
353 call test_settime(t0 + 1)
354 call feedkeys("otwo\<Esc>", 'xt')
355 set ul=100
356 call test_settime(t0 + 2)
357 call feedkeys("othree\<Esc>", 'xt')
358 set ul=100
359 w
360 wundo Xundofile
361 bwipe!
362 " restore normal timestamps.
363 call test_settime(0)
Bram Moolenaarcce293f2022-08-15 17:28:27 +0100364 new XfileEarlier
Bram Moolenaarcbd4de42017-01-07 16:14:57 +0100365 rundo Xundofile
366 earlier 1d
367 call assert_equal('', getline(1))
368 bwipe!
Bram Moolenaarcce293f2022-08-15 17:28:27 +0100369 call delete('XfileEarlier')
Bram Moolenaarcbd4de42017-01-07 16:14:57 +0100370 call delete('Xundofile')
371endfunc
Bram Moolenaar15993ce2017-10-26 20:21:44 +0200372
Bram Moolenaar559b9c62019-12-15 18:09:19 +0100373func Test_wundo_errors()
374 new
375 call setline(1, 'hello')
376 call assert_fails('wundo! Xdoesnotexist/Xundofile', 'E828:')
377 bwipe!
378endfunc
379
380" Check that reading a truncated undo file doesn't hang.
Bram Moolenaarfb06d762019-08-04 18:55:35 +0200381func Test_undofile_truncated()
382 new
383 call setline(1, 'hello')
384 set ul=100
385 wundo Xundofile
386 let contents = readfile('Xundofile', 'B')
387
388 " try several sizes
389 for size in range(20, 500, 33)
Bram Moolenaar5b148ef2022-10-15 21:35:56 +0100390 call writefile(contents[0:size], 'Xundofile', 'D')
Bram Moolenaarfb06d762019-08-04 18:55:35 +0200391 call assert_fails('rundo Xundofile', 'E825:')
392 endfor
393
394 bwipe!
Bram Moolenaarfb06d762019-08-04 18:55:35 +0200395endfunc
396
Bram Moolenaar559b9c62019-12-15 18:09:19 +0100397func Test_rundo_errors()
398 call assert_fails('rundo XfileDoesNotExist', 'E822:')
399
Bram Moolenaar5b148ef2022-10-15 21:35:56 +0100400 call writefile(['abc'], 'Xundofile', 'D')
Bram Moolenaar559b9c62019-12-15 18:09:19 +0100401 call assert_fails('rundo Xundofile', 'E823:')
Bram Moolenaar559b9c62019-12-15 18:09:19 +0100402endfunc
403
Bram Moolenaar55b419b2020-10-04 19:56:39 +0200404func Test_undofile_next()
405 set undofile
406 new Xfoo.txt
407 execute "norm ix\<c-g>uy\<c-g>uz\<Esc>"
408 write
409 bwipe
410
411 next Xfoo.txt
412 call assert_equal('xyz', getline(1))
413 silent undo
414 call assert_equal('xy', getline(1))
415 silent undo
416 call assert_equal('x', getline(1))
417 bwipe!
418
419 call delete('Xfoo.txt')
420 call delete('.Xfoo.txt.un~')
421 set undofile&
422endfunc
423
Bram Moolenaar15993ce2017-10-26 20:21:44 +0200424" Test for undo working properly when executing commands from a register.
425" Also test this in an empty buffer.
426func Test_cmd_in_reg_undo()
427 enew!
Bram Moolenaare5fa1112018-05-26 18:46:30 +0200428 let @a = "Ox\<Esc>jAy\<Esc>kdd"
Bram Moolenaar15993ce2017-10-26 20:21:44 +0200429 edit +/^$ test_undo.vim
430 normal @au
431 call assert_equal(0, &modified)
432 return
433 new
434 normal @au
435 call assert_equal(0, &modified)
436 only!
Bram Moolenaare5fa1112018-05-26 18:46:30 +0200437 let @a = ''
Bram Moolenaar15993ce2017-10-26 20:21:44 +0200438endfunc
Bram Moolenaar95dbcbe2018-01-27 21:01:34 +0100439
440" This used to cause an illegal memory access
441func Test_undo_append()
442 new
443 call feedkeys("axx\<Esc>v", 'xt')
444 undo
445 norm o
446 quit
447endfunc
Bram Moolenaarce46d932018-01-30 22:46:06 +0100448
449func Test_undo_0()
450 new
451 set ul=100
452 normal i1
453 undo
454 normal i2
455 undo
456 normal i3
457
458 undo 0
459 let d = undotree()
460 call assert_equal('', getline(1))
461 call assert_equal(0, d.seq_cur)
462
463 redo
464 let d = undotree()
465 call assert_equal('3', getline(1))
466 call assert_equal(3, d.seq_cur)
467
468 undo 2
469 undo 0
470 let d = undotree()
471 call assert_equal('', getline(1))
472 call assert_equal(0, d.seq_cur)
473
474 redo
475 let d = undotree()
476 call assert_equal('2', getline(1))
477 call assert_equal(2, d.seq_cur)
478
479 undo 1
480 undo 0
481 let d = undotree()
482 call assert_equal('', getline(1))
483 call assert_equal(0, d.seq_cur)
484
485 redo
486 let d = undotree()
487 call assert_equal('1', getline(1))
488 call assert_equal(1, d.seq_cur)
489
490 bwipe!
491endfunc
Bram Moolenaarf12519d2018-02-06 22:52:49 +0100492
Bram Moolenaar559b9c62019-12-15 18:09:19 +0100493" undo or redo are noop if there is nothing to undo or redo
494func Test_undo_redo_noop()
495 new
496 call assert_fails('undo 2', 'E830:')
497
498 message clear
499 undo
500 let messages = split(execute('message'), "\n")
501 call assert_equal('Already at oldest change', messages[-1])
502
503 message clear
504 redo
505 let messages = split(execute('message'), "\n")
506 call assert_equal('Already at newest change', messages[-1])
507
508 bwipe!
509endfunc
510
Bram Moolenaarf12519d2018-02-06 22:52:49 +0100511func Test_redo_empty_line()
512 new
513 exe "norm\x16r\x160"
514 exe "norm."
515 bwipe!
516endfunc
Bram Moolenaare5fa1112018-05-26 18:46:30 +0200517
518funct Test_undofile()
519 " Test undofile() without setting 'undodir'.
520 if has('persistent_undo')
521 call assert_equal(fnamemodify('.Xundofoo.un~', ':p'), undofile('Xundofoo'))
522 else
523 call assert_equal('', undofile('Xundofoo'))
524 endif
525 call assert_equal('', undofile(''))
526
527 " Test undofile() with 'undodir' set to to an existing directory.
528 call mkdir('Xundodir')
529 set undodir=Xundodir
530 let cwd = getcwd()
531 if has('win32')
532 " Replace windows drive such as C:... into C%...
Bram Moolenaar56242f22018-12-14 15:48:48 +0100533 let cwd = substitute(cwd, '^\([a-zA-Z]\):', '\1%', 'g')
Bram Moolenaare5fa1112018-05-26 18:46:30 +0200534 endif
535 let cwd = substitute(cwd . '/Xundofoo', '/', '%', 'g')
536 if has('persistent_undo')
537 call assert_equal('Xundodir/' . cwd, undofile('Xundofoo'))
538 else
539 call assert_equal('', undofile('Xundofoo'))
540 endif
541 call assert_equal('', undofile(''))
542 call delete('Xundodir', 'd')
543
544 " Test undofile() with 'undodir' set to a non-existing directory.
Bram Moolenaarf92e58c2019-09-08 21:51:41 +0200545 call assert_equal('', 'Xundofoo'->undofile())
Bram Moolenaare5fa1112018-05-26 18:46:30 +0200546
Bram Moolenaar077ff432019-10-28 00:42:21 +0100547 if !has('win32') && isdirectory('/tmp')
Bram Moolenaare9ebc9a2019-05-19 15:27:14 +0200548 set undodir=/tmp
Bram Moolenaar2b39d802019-05-19 16:38:56 +0200549 if has('osx')
550 call assert_equal('/tmp/%private%tmp%file', undofile('///tmp/file'))
551 else
552 call assert_equal('/tmp/%tmp%file', undofile('///tmp/file'))
553 endif
Bram Moolenaare9ebc9a2019-05-19 15:27:14 +0200554 endif
555
Bram Moolenaare5fa1112018-05-26 18:46:30 +0200556 set undodir&
557endfunc
Bram Moolenaar3e2d1c82019-12-14 20:35:01 +0100558
559" Tests for the undo file
560" Explicitly break changes up in undo-able pieces by setting 'undolevels'.
561func Test_undofile_2()
562 set undolevels=100 undofile
563 edit Xtestfile
564 call append(0, 'this is one line')
565 call cursor(1, 1)
566
567 " first a simple one-line change.
568 set undolevels=100
569 s/one/ONE/
570 set undolevels=100
571 write
572 bwipe!
573 edit Xtestfile
574 undo
575 call assert_equal('this is one line', getline(1))
576
577 " change in original file fails check
578 set noundofile
579 edit! Xtestfile
580 s/line/Line/
581 write
582 set undofile
583 bwipe!
584 edit Xtestfile
585 undo
586 call assert_equal('this is ONE Line', getline(1))
587
588 " add 10 lines, delete 6 lines, undo 3
589 set undofile
Bram Moolenaarb8bd2e62021-08-21 17:13:14 +0200590 call setbufline('%', 1, ['one', 'two', 'three', 'four', 'five', 'six',
Bram Moolenaar3e2d1c82019-12-14 20:35:01 +0100591 \ 'seven', 'eight', 'nine', 'ten'])
592 set undolevels=100
593 normal 3Gdd
594 set undolevels=100
595 normal dd
596 set undolevels=100
597 normal dd
598 set undolevels=100
599 normal dd
600 set undolevels=100
601 normal dd
602 set undolevels=100
603 normal dd
604 set undolevels=100
605 write
606 bwipe!
607 edit Xtestfile
608 normal uuu
609 call assert_equal(['one', 'two', 'six', 'seven', 'eight', 'nine', 'ten'],
610 \ getline(1, '$'))
611
612 " Test that reading the undofiles when setting undofile works
613 set noundofile undolevels=0
614 exe "normal i\n"
615 undo
616 edit! Xtestfile
617 set undofile undolevels=100
618 normal uuuuuu
619 call assert_equal(['one', 'two', 'three', 'four', 'five', 'six', 'seven',
620 \ 'eight', 'nine', 'ten'], getline(1, '$'))
621
622 bwipe!
623 call delete('Xtestfile')
624 let ufile = has('vms') ? '_un_Xtestfile' : '.Xtestfile.un~'
625 call delete(ufile)
626 set undofile& undolevels&
627endfunc
628
629" Test 'undofile' using a file encrypted with 'zip' crypt method
630func Test_undofile_cryptmethod_zip()
631 edit Xtestfile
632 set undofile cryptmethod=zip
633 call append(0, ['monday', 'tuesday', 'wednesday', 'thursday', 'friday'])
634 call cursor(5, 1)
635
636 set undolevels=100
637 normal kkkdd
638 set undolevels=100
639 normal dd
640 set undolevels=100
641 normal dd
642 set undolevels=100
643 " encrypt the file using key 'foobar'
644 call feedkeys("foobar\nfoobar\n")
645 X
646 write!
647 bwipe!
648
649 call feedkeys("foobar\n")
650 edit Xtestfile
651 set key=
652 normal uu
653 call assert_equal(['monday', 'wednesday', 'thursday', 'friday', ''],
654 \ getline(1, '$'))
655
656 bwipe!
657 call delete('Xtestfile')
658 let ufile = has('vms') ? '_un_Xtestfile' : '.Xtestfile.un~'
659 call delete(ufile)
660 set undofile& undolevels& cryptmethod&
661endfunc
662
663" Test 'undofile' using a file encrypted with 'blowfish' crypt method
664func Test_undofile_cryptmethod_blowfish()
665 edit Xtestfile
666 set undofile cryptmethod=blowfish
667 call append(0, ['jan', 'feb', 'mar', 'apr', 'jun'])
668 call cursor(5, 1)
669
670 set undolevels=100
671 exe 'normal kk0ifoo '
672 set undolevels=100
673 normal dd
674 set undolevels=100
675 exe 'normal ibar '
676 set undolevels=100
677 " encrypt the file using key 'foobar'
678 call feedkeys("foobar\nfoobar\n")
679 X
680 write!
681 bwipe!
682
683 call feedkeys("foobar\n")
684 edit Xtestfile
685 set key=
686 call search('bar')
687 call assert_equal('bar apr', getline('.'))
688 undo
689 call assert_equal('apr', getline('.'))
690 undo
691 call assert_equal('foo mar', getline('.'))
692 undo
693 call assert_equal('mar', getline('.'))
694
695 bwipe!
696 call delete('Xtestfile')
697 let ufile = has('vms') ? '_un_Xtestfile' : '.Xtestfile.un~'
698 call delete(ufile)
699 set undofile& undolevels& cryptmethod&
700endfunc
701
702" Test 'undofile' using a file encrypted with 'blowfish2' crypt method
703func Test_undofile_cryptmethod_blowfish2()
704 edit Xtestfile
705 set undofile cryptmethod=blowfish2
706 call append(0, ['jan', 'feb', 'mar', 'apr', 'jun'])
707 call cursor(5, 1)
708
709 set undolevels=100
710 exe 'normal kk0ifoo '
711 set undolevels=100
712 normal dd
713 set undolevels=100
714 exe 'normal ibar '
715 set undolevels=100
716 " encrypt the file using key 'foo2bar'
717 call feedkeys("foo2bar\nfoo2bar\n")
718 X
719 write!
720 bwipe!
721
722 call feedkeys("foo2bar\n")
723 edit Xtestfile
724 set key=
725 call search('bar')
726 call assert_equal('bar apr', getline('.'))
727 normal u
728 call assert_equal('apr', getline('.'))
729 normal u
730 call assert_equal('foo mar', getline('.'))
731 normal u
732 call assert_equal('mar', getline('.'))
733
734 bwipe!
735 call delete('Xtestfile')
736 let ufile = has('vms') ? '_un_Xtestfile' : '.Xtestfile.un~'
737 call delete(ufile)
738 set undofile& undolevels& cryptmethod&
739endfunc
740
Bram Moolenaarf4fcedc2021-03-15 18:36:20 +0100741" Test for redoing with incrementing numbered registers
742func Test_redo_repeat_numbered_register()
743 new
744 for [i, v] in [[1, 'one'], [2, 'two'], [3, 'three'],
745 \ [4, 'four'], [5, 'five'], [6, 'six'],
746 \ [7, 'seven'], [8, 'eight'], [9, 'nine']]
747 exe 'let @' .. i .. '="' .. v .. '\n"'
748 endfor
749 call feedkeys('"1p.........', 'xt')
750 call assert_equal(['', 'one', 'two', 'three', 'four', 'five', 'six',
751 \ 'seven', 'eight', 'nine', 'nine'], getline(1, '$'))
752 bwipe!
753endfunc
754
Bram Moolenaar1f448d92021-03-22 19:37:06 +0100755" Test for redo in insert mode using CTRL-O with multibyte characters
756func Test_redo_multibyte_in_insert_mode()
757 new
758 call feedkeys("a\<C-K>ft", 'xt')
759 call feedkeys("uiHe\<C-O>.llo", 'xt')
760 call assert_equal("He\ufb05llo", getline(1))
761 bwipe!
762endfunc
763
LemonBoy82444ce2022-05-12 15:39:31 +0100764func Test_undo_mark()
765 new
766 " The undo is applied to the only line.
767 call setline(1, 'hello')
768 call feedkeys("ggyiw$p", 'xt')
769 undo
770 call assert_equal([0, 1, 1, 0], getpos("'["))
771 call assert_equal([0, 1, 1, 0], getpos("']"))
772 " The undo removes the last line.
773 call feedkeys("Goaaaa\<Esc>", 'xt')
774 call feedkeys("obbbb\<Esc>", 'xt')
775 undo
776 call assert_equal([0, 2, 1, 0], getpos("'["))
777 call assert_equal([0, 2, 1, 0], getpos("']"))
778 bwipe!
779endfunc
780
Bram Moolenaar3f8f8272022-12-08 21:49:35 +0000781func Test_undo_after_write()
782 " use a terminal to make undo work like when text is typed
783 CheckRunVimInTerminal
784
785 let lines =<< trim END
786 edit Xtestfile.txt
787 set undolevels=100 undofile
788 imap . <Cmd>write<CR>
789 write
790 END
791 call writefile(lines, 'Xtest_undo_after_write', 'D')
792 let buf = RunVimInTerminal('-S Xtest_undo_after_write', #{rows: 6})
793
794 call term_sendkeys(buf, "Otest.\<CR>boo!!!\<Esc>")
795 sleep 100m
796 call term_sendkeys(buf, "u")
797 call VerifyScreenDump(buf, 'Test_undo_after_write_1', {})
798
799 call term_sendkeys(buf, "u")
800 call VerifyScreenDump(buf, 'Test_undo_after_write_2', {})
801
802 call StopVimInTerminal(buf)
803 call delete('Xtestfile.txt')
804endfunc
805
806
Bram Moolenaar3e2d1c82019-12-14 20:35:01 +0100807" vim: shiftwidth=2 sts=2 expandtab