xref: /vim-8.2.3635/src/testdir/test_undo.vim (revision b8bd2e6e)
1170b10b4SBram Moolenaar" Tests for the undo tree.
2170b10b4SBram Moolenaar" Since this script is sourced we need to explicitly break changes up in
3170b10b4SBram Moolenaar" undo-able pieces.  Do that by setting 'undolevels'.
4170b10b4SBram Moolenaar" Also tests :earlier and :later.
5170b10b4SBram Moolenaar
6170b10b4SBram Moolenaarfunc Test_undotree()
780eaddd3SBram Moolenaar  new
880eaddd3SBram Moolenaar
980eaddd3SBram Moolenaar  normal! Aabc
10170b10b4SBram Moolenaar  set ul=100
11170b10b4SBram Moolenaar  let d = undotree()
1280eaddd3SBram Moolenaar  call assert_equal(1, d.seq_last)
1380eaddd3SBram Moolenaar  call assert_equal(1, d.seq_cur)
1480eaddd3SBram Moolenaar  call assert_equal(0, d.save_last)
1580eaddd3SBram Moolenaar  call assert_equal(0, d.save_cur)
1680eaddd3SBram Moolenaar  call assert_equal(1, len(d.entries))
1780eaddd3SBram Moolenaar  call assert_equal(1, d.entries[0].newhead)
1880eaddd3SBram Moolenaar  call assert_equal(1, d.entries[0].seq)
1980eaddd3SBram Moolenaar  call assert_true(d.entries[0].time <= d.time_cur)
2080eaddd3SBram Moolenaar
2180eaddd3SBram Moolenaar  normal! Adef
2280eaddd3SBram Moolenaar  set ul=100
2380eaddd3SBram Moolenaar  let d = undotree()
2480eaddd3SBram Moolenaar  call assert_equal(2, d.seq_last)
2580eaddd3SBram Moolenaar  call assert_equal(2, d.seq_cur)
2680eaddd3SBram Moolenaar  call assert_equal(0, d.save_last)
2780eaddd3SBram Moolenaar  call assert_equal(0, d.save_cur)
2880eaddd3SBram Moolenaar  call assert_equal(2, len(d.entries))
2980eaddd3SBram Moolenaar  call assert_equal(1, d.entries[0].seq)
3080eaddd3SBram Moolenaar  call assert_equal(1, d.entries[1].newhead)
3180eaddd3SBram Moolenaar  call assert_equal(2, d.entries[1].seq)
3280eaddd3SBram Moolenaar  call assert_true(d.entries[1].time <= d.time_cur)
3380eaddd3SBram Moolenaar
3480eaddd3SBram Moolenaar  undo
3580eaddd3SBram Moolenaar  set ul=100
3680eaddd3SBram Moolenaar  let d = undotree()
3780eaddd3SBram Moolenaar  call assert_equal(2, d.seq_last)
3880eaddd3SBram Moolenaar  call assert_equal(1, d.seq_cur)
3980eaddd3SBram Moolenaar  call assert_equal(0, d.save_last)
4080eaddd3SBram Moolenaar  call assert_equal(0, d.save_cur)
4180eaddd3SBram Moolenaar  call assert_equal(2, len(d.entries))
4280eaddd3SBram Moolenaar  call assert_equal(1, d.entries[0].seq)
4380eaddd3SBram Moolenaar  call assert_equal(1, d.entries[1].curhead)
4480eaddd3SBram Moolenaar  call assert_equal(1, d.entries[1].newhead)
4580eaddd3SBram Moolenaar  call assert_equal(2, d.entries[1].seq)
4680eaddd3SBram Moolenaar  call assert_true(d.entries[1].time == d.time_cur)
4780eaddd3SBram Moolenaar
4880eaddd3SBram Moolenaar  normal! Aghi
4980eaddd3SBram Moolenaar  set ul=100
5080eaddd3SBram Moolenaar  let d = undotree()
5180eaddd3SBram Moolenaar  call assert_equal(3, d.seq_last)
5280eaddd3SBram Moolenaar  call assert_equal(3, d.seq_cur)
5380eaddd3SBram Moolenaar  call assert_equal(0, d.save_last)
5480eaddd3SBram Moolenaar  call assert_equal(0, d.save_cur)
5580eaddd3SBram Moolenaar  call assert_equal(2, len(d.entries))
5680eaddd3SBram Moolenaar  call assert_equal(1, d.entries[0].seq)
5780eaddd3SBram Moolenaar  call assert_equal(2, d.entries[1].alt[0].seq)
5880eaddd3SBram Moolenaar  call assert_equal(1, d.entries[1].newhead)
5980eaddd3SBram Moolenaar  call assert_equal(3, d.entries[1].seq)
6080eaddd3SBram Moolenaar  call assert_true(d.entries[1].time <= d.time_cur)
6180eaddd3SBram Moolenaar
6280eaddd3SBram Moolenaar  undo
6380eaddd3SBram Moolenaar  set ul=100
6480eaddd3SBram Moolenaar  let d = undotree()
6580eaddd3SBram Moolenaar  call assert_equal(3, d.seq_last)
6680eaddd3SBram Moolenaar  call assert_equal(1, d.seq_cur)
6780eaddd3SBram Moolenaar  call assert_equal(0, d.save_last)
6880eaddd3SBram Moolenaar  call assert_equal(0, d.save_cur)
6980eaddd3SBram Moolenaar  call assert_equal(2, len(d.entries))
7080eaddd3SBram Moolenaar  call assert_equal(1, d.entries[0].seq)
7180eaddd3SBram Moolenaar  call assert_equal(2, d.entries[1].alt[0].seq)
7280eaddd3SBram Moolenaar  call assert_equal(1, d.entries[1].curhead)
7380eaddd3SBram Moolenaar  call assert_equal(1, d.entries[1].newhead)
7480eaddd3SBram Moolenaar  call assert_equal(3, d.entries[1].seq)
7580eaddd3SBram Moolenaar  call assert_true(d.entries[1].time == d.time_cur)
76170b10b4SBram Moolenaar
77170b10b4SBram Moolenaar  w! Xtest
7880eaddd3SBram Moolenaar  let d = undotree()
7980eaddd3SBram Moolenaar  call assert_equal(1, d.save_cur)
8080eaddd3SBram Moolenaar  call assert_equal(1, d.save_last)
81170b10b4SBram Moolenaar  call delete('Xtest')
8280eaddd3SBram Moolenaar  bwipe! Xtest
83170b10b4SBram Moolenaarendfunc
84170b10b4SBram Moolenaar
85170b10b4SBram Moolenaarfunc FillBuffer()
86170b10b4SBram Moolenaar  for i in range(1,13)
87170b10b4SBram Moolenaar    put=i
88170b10b4SBram Moolenaar    " Set 'undolevels' to split undo.
89170b10b4SBram Moolenaar    exe "setg ul=" . &g:ul
90170b10b4SBram Moolenaar  endfor
91170b10b4SBram Moolenaarendfunc
92170b10b4SBram Moolenaar
93170b10b4SBram Moolenaarfunc Test_global_local_undolevels()
94170b10b4SBram Moolenaar  new one
95170b10b4SBram Moolenaar  set undolevels=5
96170b10b4SBram Moolenaar  call FillBuffer()
97170b10b4SBram Moolenaar  " will only undo the last 5 changes, end up with 13 - (5 + 1) = 7 lines
98170b10b4SBram Moolenaar  earlier 10
99170b10b4SBram Moolenaar  call assert_equal(5, &g:undolevels)
100170b10b4SBram Moolenaar  call assert_equal(-123456, &l:undolevels)
101170b10b4SBram Moolenaar  call assert_equal('7', getline('$'))
102170b10b4SBram Moolenaar
103170b10b4SBram Moolenaar  new two
104170b10b4SBram Moolenaar  setlocal undolevels=2
105170b10b4SBram Moolenaar  call FillBuffer()
106170b10b4SBram Moolenaar  " will only undo the last 2 changes, end up with 13 - (2 + 1) = 10 lines
107170b10b4SBram Moolenaar  earlier 10
108170b10b4SBram Moolenaar  call assert_equal(5, &g:undolevels)
109170b10b4SBram Moolenaar  call assert_equal(2, &l:undolevels)
110170b10b4SBram Moolenaar  call assert_equal('10', getline('$'))
111170b10b4SBram Moolenaar
112170b10b4SBram Moolenaar  setlocal ul=10
113170b10b4SBram Moolenaar  call assert_equal(5, &g:undolevels)
114170b10b4SBram Moolenaar  call assert_equal(10, &l:undolevels)
115170b10b4SBram Moolenaar
116170b10b4SBram Moolenaar  " Setting local value in "two" must not change local value in "one"
117170b10b4SBram Moolenaar  wincmd p
118170b10b4SBram Moolenaar  call assert_equal(5, &g:undolevels)
119170b10b4SBram Moolenaar  call assert_equal(-123456, &l:undolevels)
120170b10b4SBram Moolenaar
121170b10b4SBram Moolenaar  new three
122170b10b4SBram Moolenaar  setglobal ul=50
123170b10b4SBram Moolenaar  call assert_equal(50, &g:undolevels)
124170b10b4SBram Moolenaar  call assert_equal(-123456, &l:undolevels)
125170b10b4SBram Moolenaar
1261363a30cSBram Moolenaar  " Resetting the local 'undolevels' value to use the global value
1271363a30cSBram Moolenaar  setlocal undolevels=5
1281363a30cSBram Moolenaar  setlocal undolevels<
1291363a30cSBram Moolenaar  call assert_equal(-123456, &l:undolevels)
1301363a30cSBram Moolenaar
131170b10b4SBram Moolenaar  " Drop created windows
132170b10b4SBram Moolenaar  set ul&
133170b10b4SBram Moolenaar  new
134170b10b4SBram Moolenaar  only!
135170b10b4SBram Moolenaarendfunc
136170b10b4SBram Moolenaar
137170b10b4SBram Moolenaarfunc BackOne(expected)
138170b10b4SBram Moolenaar  call feedkeys('g-', 'xt')
139170b10b4SBram Moolenaar  call assert_equal(a:expected, getline(1))
140170b10b4SBram Moolenaarendfunc
141170b10b4SBram Moolenaar
142170b10b4SBram Moolenaarfunc Test_undo_del_chars()
143170b10b4SBram Moolenaar  " Setup a buffer without creating undo entries
144170b10b4SBram Moolenaar  new
145170b10b4SBram Moolenaar  set ul=-1
146170b10b4SBram Moolenaar  call setline(1, ['123-456'])
147170b10b4SBram Moolenaar  set ul=100
148170b10b4SBram Moolenaar  1
149170b10b4SBram Moolenaar  call test_settime(100)
150170b10b4SBram Moolenaar
151170b10b4SBram Moolenaar  " Delete three characters and undo with g-
152170b10b4SBram Moolenaar  call feedkeys('x', 'xt')
153170b10b4SBram Moolenaar  call feedkeys('x', 'xt')
154170b10b4SBram Moolenaar  call feedkeys('x', 'xt')
155170b10b4SBram Moolenaar  call assert_equal('-456', getline(1))
156170b10b4SBram Moolenaar  call BackOne('3-456')
157170b10b4SBram Moolenaar  call BackOne('23-456')
158170b10b4SBram Moolenaar  call BackOne('123-456')
159170b10b4SBram Moolenaar  call assert_fails("BackOne('123-456')")
160170b10b4SBram Moolenaar
161170b10b4SBram Moolenaar  :" Delete three other characters and go back in time with g-
162170b10b4SBram Moolenaar  call feedkeys('$x', 'xt')
163170b10b4SBram Moolenaar  call feedkeys('x', 'xt')
164170b10b4SBram Moolenaar  call feedkeys('x', 'xt')
165170b10b4SBram Moolenaar  call assert_equal('123-', getline(1))
166170b10b4SBram Moolenaar  call test_settime(101)
167170b10b4SBram Moolenaar
168170b10b4SBram Moolenaar  call BackOne('123-4')
169170b10b4SBram Moolenaar  call BackOne('123-45')
170170b10b4SBram Moolenaar  " skips '123-456' because it's older
171170b10b4SBram Moolenaar  call BackOne('-456')
172170b10b4SBram Moolenaar  call BackOne('3-456')
173170b10b4SBram Moolenaar  call BackOne('23-456')
174170b10b4SBram Moolenaar  call BackOne('123-456')
175170b10b4SBram Moolenaar  call assert_fails("BackOne('123-456')")
176170b10b4SBram Moolenaar  normal 10g+
177170b10b4SBram Moolenaar  call assert_equal('123-', getline(1))
178170b10b4SBram Moolenaar
179170b10b4SBram Moolenaar  :" Jump two seconds and go some seconds forward and backward
180170b10b4SBram Moolenaar  call test_settime(103)
181170b10b4SBram Moolenaar  call feedkeys("Aa\<Esc>", 'xt')
182170b10b4SBram Moolenaar  call feedkeys("Ab\<Esc>", 'xt')
183170b10b4SBram Moolenaar  call feedkeys("Ac\<Esc>", 'xt')
184170b10b4SBram Moolenaar  call assert_equal('123-abc', getline(1))
185170b10b4SBram Moolenaar  earlier 1s
186170b10b4SBram Moolenaar  call assert_equal('123-', getline(1))
187170b10b4SBram Moolenaar  earlier 3s
188170b10b4SBram Moolenaar  call assert_equal('123-456', getline(1))
189170b10b4SBram Moolenaar  later 1s
190170b10b4SBram Moolenaar  call assert_equal('123-', getline(1))
191170b10b4SBram Moolenaar  later 1h
192170b10b4SBram Moolenaar  call assert_equal('123-abc', getline(1))
193170b10b4SBram Moolenaar
194170b10b4SBram Moolenaar  close!
195170b10b4SBram Moolenaarendfunc
196170b10b4SBram Moolenaar
197c628fdcdSBram Moolenaarfunc Test_undolist()
198c628fdcdSBram Moolenaar  new
199c628fdcdSBram Moolenaar  set ul=100
200c628fdcdSBram Moolenaar
201c628fdcdSBram Moolenaar  let a = execute('undolist')
202c628fdcdSBram Moolenaar  call assert_equal("\nNothing to undo", a)
203c628fdcdSBram Moolenaar
204c628fdcdSBram Moolenaar  " 1 leaf (2 changes).
205c628fdcdSBram Moolenaar  call feedkeys('achange1', 'xt')
206c628fdcdSBram Moolenaar  call feedkeys('achange2', 'xt')
207c628fdcdSBram Moolenaar  let a = execute('undolist')
208c628fdcdSBram Moolenaar  call assert_match("^\nnumber changes  when  *saved\n *2  *2 .*$", a)
209c628fdcdSBram Moolenaar
210c628fdcdSBram Moolenaar  " 2 leaves.
211c628fdcdSBram Moolenaar  call feedkeys('u', 'xt')
212c628fdcdSBram Moolenaar  call feedkeys('achange3\<Esc>', 'xt')
213c628fdcdSBram Moolenaar  let a = execute('undolist')
214c628fdcdSBram Moolenaar  call assert_match("^\nnumber changes  when  *saved\n *2  *2  *.*\n *3  *2 .*$", a)
215c628fdcdSBram Moolenaar  close!
216c628fdcdSBram Moolenaarendfunc
217c628fdcdSBram Moolenaar
218c628fdcdSBram Moolenaarfunc Test_U_command()
219c628fdcdSBram Moolenaar  new
220c628fdcdSBram Moolenaar  set ul=100
221c628fdcdSBram Moolenaar  call feedkeys("achange1\<Esc>", 'xt')
222c628fdcdSBram Moolenaar  call feedkeys("achange2\<Esc>", 'xt')
223c628fdcdSBram Moolenaar  norm! U
224c628fdcdSBram Moolenaar  call assert_equal('', getline(1))
225c628fdcdSBram Moolenaar  norm! U
226c628fdcdSBram Moolenaar  call assert_equal('change1change2', getline(1))
227c628fdcdSBram Moolenaar  close!
228c628fdcdSBram Moolenaarendfunc
229c628fdcdSBram Moolenaar
230170b10b4SBram Moolenaarfunc Test_undojoin()
231170b10b4SBram Moolenaar  new
232170b10b4SBram Moolenaar  call feedkeys("Goaaaa\<Esc>", 'xt')
233170b10b4SBram Moolenaar  call feedkeys("obbbb\<Esc>", 'xt')
234170b10b4SBram Moolenaar  call assert_equal(['aaaa', 'bbbb'], getline(2, '$'))
235170b10b4SBram Moolenaar  call feedkeys("u", 'xt')
236170b10b4SBram Moolenaar  call assert_equal(['aaaa'], getline(2, '$'))
237170b10b4SBram Moolenaar  call feedkeys("obbbb\<Esc>", 'xt')
238170b10b4SBram Moolenaar  undojoin
239170b10b4SBram Moolenaar  " Note: next change must not be as if typed
240170b10b4SBram Moolenaar  call feedkeys("occcc\<Esc>", 'x')
241170b10b4SBram Moolenaar  call assert_equal(['aaaa', 'bbbb', 'cccc'], getline(2, '$'))
242170b10b4SBram Moolenaar  call feedkeys("u", 'xt')
243170b10b4SBram Moolenaar  call assert_equal(['aaaa'], getline(2, '$'))
2445e4e1b12SBram Moolenaar  bwipe!
2455e4e1b12SBram Moolenaarendfunc
2465e4e1b12SBram Moolenaar
2475e4e1b12SBram Moolenaarfunc Test_undojoin_redo()
2485e4e1b12SBram Moolenaar  new
2495e4e1b12SBram Moolenaar  call setline(1, ['first line', 'second line'])
2505e4e1b12SBram Moolenaar  call feedkeys("ixx\<Esc>", 'xt')
2515e4e1b12SBram Moolenaar  call feedkeys(":undojoin | redo\<CR>", 'xt')
2525e4e1b12SBram Moolenaar  call assert_equal('xxfirst line', getline(1))
2535e4e1b12SBram Moolenaar  call assert_equal('second line', getline(2))
2545e4e1b12SBram Moolenaar  bwipe!
255170b10b4SBram Moolenaarendfunc
256170b10b4SBram Moolenaar
257559b9c68SBram Moolenaar" undojoin not allowed after undo
258559b9c68SBram Moolenaarfunc Test_undojoin_after_undo()
259559b9c68SBram Moolenaar  new
260559b9c68SBram Moolenaar  call feedkeys("ixx\<Esc>u", 'xt')
261559b9c68SBram Moolenaar  call assert_fails(':undojoin', 'E790:')
262559b9c68SBram Moolenaar  bwipe!
263559b9c68SBram Moolenaarendfunc
264559b9c68SBram Moolenaar
265559b9c68SBram Moolenaar" undojoin is a noop when no change yet, or when 'undolevels' is negative
266559b9c68SBram Moolenaarfunc Test_undojoin_noop()
267559b9c68SBram Moolenaar  new
268559b9c68SBram Moolenaar  call feedkeys(":undojoin\<CR>", 'xt')
269559b9c68SBram Moolenaar  call assert_equal([''], getline(1, '$'))
270559b9c68SBram Moolenaar  setlocal undolevels=-1
271559b9c68SBram Moolenaar  call feedkeys("ixx\<Esc>u", 'xt')
272559b9c68SBram Moolenaar  call feedkeys(":undojoin\<CR>", 'xt')
273559b9c68SBram Moolenaar  call assert_equal(['xx'], getline(1, '$'))
274559b9c68SBram Moolenaar  bwipe!
275559b9c68SBram Moolenaarendfunc
276559b9c68SBram Moolenaar
277170b10b4SBram Moolenaarfunc Test_undo_write()
2785842a748SBram Moolenaar  call delete('Xtest')
279170b10b4SBram Moolenaar  split Xtest
280170b10b4SBram Moolenaar  call feedkeys("ione one one\<Esc>", 'xt')
281170b10b4SBram Moolenaar  w!
282170b10b4SBram Moolenaar  call feedkeys("otwo\<Esc>", 'xt')
283170b10b4SBram Moolenaar  call feedkeys("otwo\<Esc>", 'xt')
284170b10b4SBram Moolenaar  w
285170b10b4SBram Moolenaar  call feedkeys("othree\<Esc>", 'xt')
286170b10b4SBram Moolenaar  call assert_equal(['one one one', 'two', 'two', 'three'], getline(1, '$'))
287170b10b4SBram Moolenaar  earlier 1f
288170b10b4SBram Moolenaar  call assert_equal(['one one one', 'two', 'two'], getline(1, '$'))
289170b10b4SBram Moolenaar  earlier 1f
290170b10b4SBram Moolenaar  call assert_equal(['one one one'], getline(1, '$'))
291170b10b4SBram Moolenaar  earlier 1f
292170b10b4SBram Moolenaar  call assert_equal([''], getline(1, '$'))
293170b10b4SBram Moolenaar  later 1f
294170b10b4SBram Moolenaar  call assert_equal(['one one one'], getline(1, '$'))
295170b10b4SBram Moolenaar  later 1f
296170b10b4SBram Moolenaar  call assert_equal(['one one one', 'two', 'two'], getline(1, '$'))
297170b10b4SBram Moolenaar  later 1f
298170b10b4SBram Moolenaar  call assert_equal(['one one one', 'two', 'two', 'three'], getline(1, '$'))
299170b10b4SBram Moolenaar
300170b10b4SBram Moolenaar  close!
301170b10b4SBram Moolenaar  call delete('Xtest')
302170b10b4SBram Moolenaar  bwipe! Xtest
3039f6277bdSBram Moolenaar
3049f6277bdSBram Moolenaar  call assert_fails('earlier xyz', 'E475:')
305170b10b4SBram Moolenaarendfunc
306170b10b4SBram Moolenaar
307170b10b4SBram Moolenaarfunc Test_insert_expr()
308170b10b4SBram Moolenaar  new
309170b10b4SBram Moolenaar  " calling setline() triggers undo sync
310170b10b4SBram Moolenaar  call feedkeys("oa\<Esc>", 'xt')
311170b10b4SBram Moolenaar  call feedkeys("ob\<Esc>", 'xt')
312170b10b4SBram Moolenaar  set ul=100
313170b10b4SBram Moolenaar  call feedkeys("o1\<Esc>a2\<C-R>=setline('.','1234')\<CR>\<CR>\<Esc>", 'x')
314170b10b4SBram Moolenaar  call assert_equal(['a', 'b', '120', '34'], getline(2, '$'))
315170b10b4SBram Moolenaar  call feedkeys("u", 'x')
316170b10b4SBram Moolenaar  call assert_equal(['a', 'b', '12'], getline(2, '$'))
317170b10b4SBram Moolenaar  call feedkeys("u", 'x')
318170b10b4SBram Moolenaar  call assert_equal(['a', 'b'], getline(2, '$'))
319170b10b4SBram Moolenaar
320170b10b4SBram Moolenaar  call feedkeys("oc\<Esc>", 'xt')
321170b10b4SBram Moolenaar  set ul=100
322170b10b4SBram Moolenaar  call feedkeys("o1\<Esc>a2\<C-R>=setline('.','1234')\<CR>\<CR>\<Esc>", 'x')
323170b10b4SBram Moolenaar  call assert_equal(['a', 'b', 'c', '120', '34'], getline(2, '$'))
324170b10b4SBram Moolenaar  call feedkeys("u", 'x')
325170b10b4SBram Moolenaar  call assert_equal(['a', 'b', 'c', '12'], getline(2, '$'))
326170b10b4SBram Moolenaar
327170b10b4SBram Moolenaar  call feedkeys("od\<Esc>", 'xt')
328170b10b4SBram Moolenaar  set ul=100
329170b10b4SBram Moolenaar  call feedkeys("o1\<Esc>a2\<C-R>=string(123)\<CR>\<Esc>", 'x')
330170b10b4SBram Moolenaar  call assert_equal(['a', 'b', 'c', '12', 'd', '12123'], getline(2, '$'))
331170b10b4SBram Moolenaar  call feedkeys("u", 'x')
332170b10b4SBram Moolenaar  call assert_equal(['a', 'b', 'c', '12', 'd'], getline(2, '$'))
333170b10b4SBram Moolenaar
334170b10b4SBram Moolenaar  close!
335170b10b4SBram Moolenaarendfunc
336cbd4de44SBram Moolenaar
337cbd4de44SBram Moolenaarfunc Test_undofile_earlier()
338cbd4de44SBram Moolenaar  " Issue #1254
339cbd4de44SBram Moolenaar  " create undofile with timestamps older than Vim startup time.
340cbd4de44SBram Moolenaar  let t0 = localtime() - 43200
341cbd4de44SBram Moolenaar  call test_settime(t0)
342cbd4de44SBram Moolenaar  new Xfile
343cbd4de44SBram Moolenaar  call feedkeys("ione\<Esc>", 'xt')
344cbd4de44SBram Moolenaar  set ul=100
345cbd4de44SBram Moolenaar  call test_settime(t0 + 1)
346cbd4de44SBram Moolenaar  call feedkeys("otwo\<Esc>", 'xt')
347cbd4de44SBram Moolenaar  set ul=100
348cbd4de44SBram Moolenaar  call test_settime(t0 + 2)
349cbd4de44SBram Moolenaar  call feedkeys("othree\<Esc>", 'xt')
350cbd4de44SBram Moolenaar  set ul=100
351cbd4de44SBram Moolenaar  w
352cbd4de44SBram Moolenaar  wundo Xundofile
353cbd4de44SBram Moolenaar  bwipe!
354cbd4de44SBram Moolenaar  " restore normal timestamps.
355cbd4de44SBram Moolenaar  call test_settime(0)
356cbd4de44SBram Moolenaar  new Xfile
357cbd4de44SBram Moolenaar  rundo Xundofile
358cbd4de44SBram Moolenaar  earlier 1d
359cbd4de44SBram Moolenaar  call assert_equal('', getline(1))
360cbd4de44SBram Moolenaar  bwipe!
361cbd4de44SBram Moolenaar  call delete('Xfile')
362cbd4de44SBram Moolenaar  call delete('Xundofile')
363cbd4de44SBram Moolenaarendfunc
36415993ce9SBram Moolenaar
365559b9c68SBram Moolenaarfunc Test_wundo_errors()
366559b9c68SBram Moolenaar  new
367559b9c68SBram Moolenaar  call setline(1, 'hello')
368559b9c68SBram Moolenaar  call assert_fails('wundo! Xdoesnotexist/Xundofile', 'E828:')
369559b9c68SBram Moolenaar  bwipe!
370559b9c68SBram Moolenaarendfunc
371559b9c68SBram Moolenaar
372559b9c68SBram Moolenaar" Check that reading a truncated undo file doesn't hang.
373fb06d767SBram Moolenaarfunc Test_undofile_truncated()
374fb06d767SBram Moolenaar  new
375fb06d767SBram Moolenaar  call setline(1, 'hello')
376fb06d767SBram Moolenaar  set ul=100
377fb06d767SBram Moolenaar  wundo Xundofile
378fb06d767SBram Moolenaar  let contents = readfile('Xundofile', 'B')
379fb06d767SBram Moolenaar
380fb06d767SBram Moolenaar  " try several sizes
381fb06d767SBram Moolenaar  for size in range(20, 500, 33)
382fb06d767SBram Moolenaar    call writefile(contents[0:size], 'Xundofile')
383fb06d767SBram Moolenaar    call assert_fails('rundo Xundofile', 'E825:')
384fb06d767SBram Moolenaar  endfor
385fb06d767SBram Moolenaar
386fb06d767SBram Moolenaar  bwipe!
3879283f920SBram Moolenaar  call delete('Xundofile')
388fb06d767SBram Moolenaarendfunc
389fb06d767SBram Moolenaar
390559b9c68SBram Moolenaarfunc Test_rundo_errors()
391559b9c68SBram Moolenaar  call assert_fails('rundo XfileDoesNotExist', 'E822:')
392559b9c68SBram Moolenaar
393559b9c68SBram Moolenaar  call writefile(['abc'], 'Xundofile')
394559b9c68SBram Moolenaar  call assert_fails('rundo Xundofile', 'E823:')
395559b9c68SBram Moolenaar
396559b9c68SBram Moolenaar  call delete('Xundofile')
397559b9c68SBram Moolenaarendfunc
398559b9c68SBram Moolenaar
39955b419b8SBram Moolenaarfunc Test_undofile_next()
40055b419b8SBram Moolenaar  set undofile
40155b419b8SBram Moolenaar  new Xfoo.txt
40255b419b8SBram Moolenaar  execute "norm ix\<c-g>uy\<c-g>uz\<Esc>"
40355b419b8SBram Moolenaar  write
40455b419b8SBram Moolenaar  bwipe
40555b419b8SBram Moolenaar
40655b419b8SBram Moolenaar  next Xfoo.txt
40755b419b8SBram Moolenaar  call assert_equal('xyz', getline(1))
40855b419b8SBram Moolenaar  silent undo
40955b419b8SBram Moolenaar  call assert_equal('xy', getline(1))
41055b419b8SBram Moolenaar  silent undo
41155b419b8SBram Moolenaar  call assert_equal('x', getline(1))
41255b419b8SBram Moolenaar  bwipe!
41355b419b8SBram Moolenaar
41455b419b8SBram Moolenaar  call delete('Xfoo.txt')
41555b419b8SBram Moolenaar  call delete('.Xfoo.txt.un~')
41655b419b8SBram Moolenaar  set undofile&
41755b419b8SBram Moolenaarendfunc
41855b419b8SBram Moolenaar
41915993ce9SBram Moolenaar" Test for undo working properly when executing commands from a register.
42015993ce9SBram Moolenaar" Also test this in an empty buffer.
42115993ce9SBram Moolenaarfunc Test_cmd_in_reg_undo()
42215993ce9SBram Moolenaar  enew!
42315993ce9SBram Moolenaar  let @a = "Ox\<Esc>jAy\<Esc>kdd"
42415993ce9SBram Moolenaar  edit +/^$ test_undo.vim
42515993ce9SBram Moolenaar  normal @au
42615993ce9SBram Moolenaar  call assert_equal(0, &modified)
42715993ce9SBram Moolenaar  return
42815993ce9SBram Moolenaar  new
42915993ce9SBram Moolenaar  normal @au
43015993ce9SBram Moolenaar  call assert_equal(0, &modified)
43115993ce9SBram Moolenaar  only!
43215993ce9SBram Moolenaar  let @a = ''
43315993ce9SBram Moolenaarendfunc
43495dbcbeaSBram Moolenaar
43595dbcbeaSBram Moolenaar" This used to cause an illegal memory access
43695dbcbeaSBram Moolenaarfunc Test_undo_append()
43795dbcbeaSBram Moolenaar  new
43895dbcbeaSBram Moolenaar  call feedkeys("axx\<Esc>v", 'xt')
43995dbcbeaSBram Moolenaar  undo
44095dbcbeaSBram Moolenaar  norm o
44195dbcbeaSBram Moolenaar  quit
44295dbcbeaSBram Moolenaarendfunc
443ce46d934SBram Moolenaar
444ce46d934SBram Moolenaarfunc Test_undo_0()
445ce46d934SBram Moolenaar  new
446ce46d934SBram Moolenaar  set ul=100
447ce46d934SBram Moolenaar  normal i1
448ce46d934SBram Moolenaar  undo
449ce46d934SBram Moolenaar  normal i2
450ce46d934SBram Moolenaar  undo
451ce46d934SBram Moolenaar  normal i3
452ce46d934SBram Moolenaar
453ce46d934SBram Moolenaar  undo 0
454ce46d934SBram Moolenaar  let d = undotree()
455ce46d934SBram Moolenaar  call assert_equal('', getline(1))
456ce46d934SBram Moolenaar  call assert_equal(0, d.seq_cur)
457ce46d934SBram Moolenaar
458ce46d934SBram Moolenaar  redo
459ce46d934SBram Moolenaar  let d = undotree()
460ce46d934SBram Moolenaar  call assert_equal('3', getline(1))
461ce46d934SBram Moolenaar  call assert_equal(3, d.seq_cur)
462ce46d934SBram Moolenaar
463ce46d934SBram Moolenaar  undo 2
464ce46d934SBram Moolenaar  undo 0
465ce46d934SBram Moolenaar  let d = undotree()
466ce46d934SBram Moolenaar  call assert_equal('', getline(1))
467ce46d934SBram Moolenaar  call assert_equal(0, d.seq_cur)
468ce46d934SBram Moolenaar
469ce46d934SBram Moolenaar  redo
470ce46d934SBram Moolenaar  let d = undotree()
471ce46d934SBram Moolenaar  call assert_equal('2', getline(1))
472ce46d934SBram Moolenaar  call assert_equal(2, d.seq_cur)
473ce46d934SBram Moolenaar
474ce46d934SBram Moolenaar  undo 1
475ce46d934SBram Moolenaar  undo 0
476ce46d934SBram Moolenaar  let d = undotree()
477ce46d934SBram Moolenaar  call assert_equal('', getline(1))
478ce46d934SBram Moolenaar  call assert_equal(0, d.seq_cur)
479ce46d934SBram Moolenaar
480ce46d934SBram Moolenaar  redo
481ce46d934SBram Moolenaar  let d = undotree()
482ce46d934SBram Moolenaar  call assert_equal('1', getline(1))
483ce46d934SBram Moolenaar  call assert_equal(1, d.seq_cur)
484ce46d934SBram Moolenaar
485ce46d934SBram Moolenaar  bwipe!
486ce46d934SBram Moolenaarendfunc
487f12519deSBram Moolenaar
488559b9c68SBram Moolenaar" undo or redo are noop if there is nothing to undo or redo
489559b9c68SBram Moolenaarfunc Test_undo_redo_noop()
490559b9c68SBram Moolenaar  new
491559b9c68SBram Moolenaar  call assert_fails('undo 2', 'E830:')
492559b9c68SBram Moolenaar
493559b9c68SBram Moolenaar  message clear
494559b9c68SBram Moolenaar  undo
495559b9c68SBram Moolenaar  let messages = split(execute('message'), "\n")
496559b9c68SBram Moolenaar  call assert_equal('Already at oldest change', messages[-1])
497559b9c68SBram Moolenaar
498559b9c68SBram Moolenaar  message clear
499559b9c68SBram Moolenaar  redo
500559b9c68SBram Moolenaar  let messages = split(execute('message'), "\n")
501559b9c68SBram Moolenaar  call assert_equal('Already at newest change', messages[-1])
502559b9c68SBram Moolenaar
503559b9c68SBram Moolenaar  bwipe!
504559b9c68SBram Moolenaarendfunc
505559b9c68SBram Moolenaar
506f12519deSBram Moolenaarfunc Test_redo_empty_line()
507f12519deSBram Moolenaar  new
508f12519deSBram Moolenaar  exe "norm\x16r\x160"
509f12519deSBram Moolenaar  exe "norm."
510f12519deSBram Moolenaar  bwipe!
511e5fa1118SBram Moolenaarendfunc
512e5fa1118SBram Moolenaar
513e5fa1118SBram Moolenaarfunct Test_undofile()
514e5fa1118SBram Moolenaar  " Test undofile() without setting 'undodir'.
515e5fa1118SBram Moolenaar  if has('persistent_undo')
516e5fa1118SBram Moolenaar    call assert_equal(fnamemodify('.Xundofoo.un~', ':p'), undofile('Xundofoo'))
517e5fa1118SBram Moolenaar  else
518e5fa1118SBram Moolenaar    call assert_equal('', undofile('Xundofoo'))
519e5fa1118SBram Moolenaar  endif
520e5fa1118SBram Moolenaar  call assert_equal('', undofile(''))
521e5fa1118SBram Moolenaar
522e5fa1118SBram Moolenaar  " Test undofile() with 'undodir' set to to an existing directory.
523e5fa1118SBram Moolenaar  call mkdir('Xundodir')
524e5fa1118SBram Moolenaar  set undodir=Xundodir
525e5fa1118SBram Moolenaar  let cwd = getcwd()
526e5fa1118SBram Moolenaar  if has('win32')
527e5fa1118SBram Moolenaar    " Replace windows drive such as C:... into C%...
52856242f2bSBram Moolenaar    let cwd = substitute(cwd, '^\([a-zA-Z]\):', '\1%', 'g')
529e5fa1118SBram Moolenaar  endif
530e5fa1118SBram Moolenaar  let cwd = substitute(cwd . '/Xundofoo', '/', '%', 'g')
531e5fa1118SBram Moolenaar  if has('persistent_undo')
532e5fa1118SBram Moolenaar    call assert_equal('Xundodir/' . cwd, undofile('Xundofoo'))
533e5fa1118SBram Moolenaar  else
534e5fa1118SBram Moolenaar    call assert_equal('', undofile('Xundofoo'))
535e5fa1118SBram Moolenaar  endif
536e5fa1118SBram Moolenaar  call assert_equal('', undofile(''))
537e5fa1118SBram Moolenaar  call delete('Xundodir', 'd')
538e5fa1118SBram Moolenaar
539e5fa1118SBram Moolenaar  " Test undofile() with 'undodir' set to a non-existing directory.
540f92e58caSBram Moolenaar  call assert_equal('', 'Xundofoo'->undofile())
541e5fa1118SBram Moolenaar
542077ff436SBram Moolenaar  if !has('win32') && isdirectory('/tmp')
543e9ebc9a9SBram Moolenaar    set undodir=/tmp
5442b39d806SBram Moolenaar    if has('osx')
5452b39d806SBram Moolenaar      call assert_equal('/tmp/%private%tmp%file', undofile('///tmp/file'))
5462b39d806SBram Moolenaar    else
547e9ebc9a9SBram Moolenaar      call assert_equal('/tmp/%tmp%file', undofile('///tmp/file'))
548e9ebc9a9SBram Moolenaar    endif
5492b39d806SBram Moolenaar  endif
550e9ebc9a9SBram Moolenaar
551e5fa1118SBram Moolenaar  set undodir&
552f12519deSBram Moolenaarendfunc
5533e2d1c8cSBram Moolenaar
5543e2d1c8cSBram Moolenaar" Tests for the undo file
5553e2d1c8cSBram Moolenaar" Explicitly break changes up in undo-able pieces by setting 'undolevels'.
5563e2d1c8cSBram Moolenaarfunc Test_undofile_2()
5573e2d1c8cSBram Moolenaar  set undolevels=100 undofile
5583e2d1c8cSBram Moolenaar  edit Xtestfile
5593e2d1c8cSBram Moolenaar  call append(0, 'this is one line')
5603e2d1c8cSBram Moolenaar  call cursor(1, 1)
5613e2d1c8cSBram Moolenaar
5623e2d1c8cSBram Moolenaar  " first a simple one-line change.
5633e2d1c8cSBram Moolenaar  set undolevels=100
5643e2d1c8cSBram Moolenaar  s/one/ONE/
5653e2d1c8cSBram Moolenaar  set undolevels=100
5663e2d1c8cSBram Moolenaar  write
5673e2d1c8cSBram Moolenaar  bwipe!
5683e2d1c8cSBram Moolenaar  edit Xtestfile
5693e2d1c8cSBram Moolenaar  undo
5703e2d1c8cSBram Moolenaar  call assert_equal('this is one line', getline(1))
5713e2d1c8cSBram Moolenaar
5723e2d1c8cSBram Moolenaar  " change in original file fails check
5733e2d1c8cSBram Moolenaar  set noundofile
5743e2d1c8cSBram Moolenaar  edit! Xtestfile
5753e2d1c8cSBram Moolenaar  s/line/Line/
5763e2d1c8cSBram Moolenaar  write
5773e2d1c8cSBram Moolenaar  set undofile
5783e2d1c8cSBram Moolenaar  bwipe!
5793e2d1c8cSBram Moolenaar  edit Xtestfile
5803e2d1c8cSBram Moolenaar  undo
5813e2d1c8cSBram Moolenaar  call assert_equal('this is ONE Line', getline(1))
5823e2d1c8cSBram Moolenaar
5833e2d1c8cSBram Moolenaar  " add 10 lines, delete 6 lines, undo 3
5843e2d1c8cSBram Moolenaar  set undofile
585*b8bd2e6eSBram Moolenaar  call setbufline('%', 1, ['one', 'two', 'three', 'four', 'five', 'six',
5863e2d1c8cSBram Moolenaar	      \ 'seven', 'eight', 'nine', 'ten'])
5873e2d1c8cSBram Moolenaar  set undolevels=100
5883e2d1c8cSBram Moolenaar  normal 3Gdd
5893e2d1c8cSBram Moolenaar  set undolevels=100
5903e2d1c8cSBram Moolenaar  normal dd
5913e2d1c8cSBram Moolenaar  set undolevels=100
5923e2d1c8cSBram Moolenaar  normal dd
5933e2d1c8cSBram Moolenaar  set undolevels=100
5943e2d1c8cSBram Moolenaar  normal dd
5953e2d1c8cSBram Moolenaar  set undolevels=100
5963e2d1c8cSBram Moolenaar  normal dd
5973e2d1c8cSBram Moolenaar  set undolevels=100
5983e2d1c8cSBram Moolenaar  normal dd
5993e2d1c8cSBram Moolenaar  set undolevels=100
6003e2d1c8cSBram Moolenaar  write
6013e2d1c8cSBram Moolenaar  bwipe!
6023e2d1c8cSBram Moolenaar  edit Xtestfile
6033e2d1c8cSBram Moolenaar  normal uuu
6043e2d1c8cSBram Moolenaar  call assert_equal(['one', 'two', 'six', 'seven', 'eight', 'nine', 'ten'],
6053e2d1c8cSBram Moolenaar	      \ getline(1, '$'))
6063e2d1c8cSBram Moolenaar
6073e2d1c8cSBram Moolenaar  " Test that reading the undofiles when setting undofile works
6083e2d1c8cSBram Moolenaar  set noundofile undolevels=0
6093e2d1c8cSBram Moolenaar  exe "normal i\n"
6103e2d1c8cSBram Moolenaar  undo
6113e2d1c8cSBram Moolenaar  edit! Xtestfile
6123e2d1c8cSBram Moolenaar  set undofile undolevels=100
6133e2d1c8cSBram Moolenaar  normal uuuuuu
6143e2d1c8cSBram Moolenaar  call assert_equal(['one', 'two', 'three', 'four', 'five', 'six', 'seven',
6153e2d1c8cSBram Moolenaar	      \ 'eight', 'nine', 'ten'], getline(1, '$'))
6163e2d1c8cSBram Moolenaar
6173e2d1c8cSBram Moolenaar  bwipe!
6183e2d1c8cSBram Moolenaar  call delete('Xtestfile')
6193e2d1c8cSBram Moolenaar  let ufile = has('vms') ? '_un_Xtestfile' : '.Xtestfile.un~'
6203e2d1c8cSBram Moolenaar  call delete(ufile)
6213e2d1c8cSBram Moolenaar  set undofile& undolevels&
6223e2d1c8cSBram Moolenaarendfunc
6233e2d1c8cSBram Moolenaar
6243e2d1c8cSBram Moolenaar" Test 'undofile' using a file encrypted with 'zip' crypt method
6253e2d1c8cSBram Moolenaarfunc Test_undofile_cryptmethod_zip()
6263e2d1c8cSBram Moolenaar  edit Xtestfile
6273e2d1c8cSBram Moolenaar  set undofile cryptmethod=zip
6283e2d1c8cSBram Moolenaar  call append(0, ['monday', 'tuesday', 'wednesday', 'thursday', 'friday'])
6293e2d1c8cSBram Moolenaar  call cursor(5, 1)
6303e2d1c8cSBram Moolenaar
6313e2d1c8cSBram Moolenaar  set undolevels=100
6323e2d1c8cSBram Moolenaar  normal kkkdd
6333e2d1c8cSBram Moolenaar  set undolevels=100
6343e2d1c8cSBram Moolenaar  normal dd
6353e2d1c8cSBram Moolenaar  set undolevels=100
6363e2d1c8cSBram Moolenaar  normal dd
6373e2d1c8cSBram Moolenaar  set undolevels=100
6383e2d1c8cSBram Moolenaar  " encrypt the file using key 'foobar'
6393e2d1c8cSBram Moolenaar  call feedkeys("foobar\nfoobar\n")
6403e2d1c8cSBram Moolenaar  X
6413e2d1c8cSBram Moolenaar  write!
6423e2d1c8cSBram Moolenaar  bwipe!
6433e2d1c8cSBram Moolenaar
6443e2d1c8cSBram Moolenaar  call feedkeys("foobar\n")
6453e2d1c8cSBram Moolenaar  edit Xtestfile
6463e2d1c8cSBram Moolenaar  set key=
6473e2d1c8cSBram Moolenaar  normal uu
6483e2d1c8cSBram Moolenaar  call assert_equal(['monday', 'wednesday', 'thursday', 'friday', ''],
6493e2d1c8cSBram Moolenaar                    \ getline(1, '$'))
6503e2d1c8cSBram Moolenaar
6513e2d1c8cSBram Moolenaar  bwipe!
6523e2d1c8cSBram Moolenaar  call delete('Xtestfile')
6533e2d1c8cSBram Moolenaar  let ufile = has('vms') ? '_un_Xtestfile' : '.Xtestfile.un~'
6543e2d1c8cSBram Moolenaar  call delete(ufile)
6553e2d1c8cSBram Moolenaar  set undofile& undolevels& cryptmethod&
6563e2d1c8cSBram Moolenaarendfunc
6573e2d1c8cSBram Moolenaar
6583e2d1c8cSBram Moolenaar" Test 'undofile' using a file encrypted with 'blowfish' crypt method
6593e2d1c8cSBram Moolenaarfunc Test_undofile_cryptmethod_blowfish()
6603e2d1c8cSBram Moolenaar  edit Xtestfile
6613e2d1c8cSBram Moolenaar  set undofile cryptmethod=blowfish
6623e2d1c8cSBram Moolenaar  call append(0, ['jan', 'feb', 'mar', 'apr', 'jun'])
6633e2d1c8cSBram Moolenaar  call cursor(5, 1)
6643e2d1c8cSBram Moolenaar
6653e2d1c8cSBram Moolenaar  set undolevels=100
6663e2d1c8cSBram Moolenaar  exe 'normal kk0ifoo '
6673e2d1c8cSBram Moolenaar  set undolevels=100
6683e2d1c8cSBram Moolenaar  normal dd
6693e2d1c8cSBram Moolenaar  set undolevels=100
6703e2d1c8cSBram Moolenaar  exe 'normal ibar '
6713e2d1c8cSBram Moolenaar  set undolevels=100
6723e2d1c8cSBram Moolenaar  " encrypt the file using key 'foobar'
6733e2d1c8cSBram Moolenaar  call feedkeys("foobar\nfoobar\n")
6743e2d1c8cSBram Moolenaar  X
6753e2d1c8cSBram Moolenaar  write!
6763e2d1c8cSBram Moolenaar  bwipe!
6773e2d1c8cSBram Moolenaar
6783e2d1c8cSBram Moolenaar  call feedkeys("foobar\n")
6793e2d1c8cSBram Moolenaar  edit Xtestfile
6803e2d1c8cSBram Moolenaar  set key=
6813e2d1c8cSBram Moolenaar  call search('bar')
6823e2d1c8cSBram Moolenaar  call assert_equal('bar apr', getline('.'))
6833e2d1c8cSBram Moolenaar  undo
6843e2d1c8cSBram Moolenaar  call assert_equal('apr', getline('.'))
6853e2d1c8cSBram Moolenaar  undo
6863e2d1c8cSBram Moolenaar  call assert_equal('foo mar', getline('.'))
6873e2d1c8cSBram Moolenaar  undo
6883e2d1c8cSBram Moolenaar  call assert_equal('mar', getline('.'))
6893e2d1c8cSBram Moolenaar
6903e2d1c8cSBram Moolenaar  bwipe!
6913e2d1c8cSBram Moolenaar  call delete('Xtestfile')
6923e2d1c8cSBram Moolenaar  let ufile = has('vms') ? '_un_Xtestfile' : '.Xtestfile.un~'
6933e2d1c8cSBram Moolenaar  call delete(ufile)
6943e2d1c8cSBram Moolenaar  set undofile& undolevels& cryptmethod&
6953e2d1c8cSBram Moolenaarendfunc
6963e2d1c8cSBram Moolenaar
6973e2d1c8cSBram Moolenaar" Test 'undofile' using a file encrypted with 'blowfish2' crypt method
6983e2d1c8cSBram Moolenaarfunc Test_undofile_cryptmethod_blowfish2()
6993e2d1c8cSBram Moolenaar  edit Xtestfile
7003e2d1c8cSBram Moolenaar  set undofile cryptmethod=blowfish2
7013e2d1c8cSBram Moolenaar  call append(0, ['jan', 'feb', 'mar', 'apr', 'jun'])
7023e2d1c8cSBram Moolenaar  call cursor(5, 1)
7033e2d1c8cSBram Moolenaar
7043e2d1c8cSBram Moolenaar  set undolevels=100
7053e2d1c8cSBram Moolenaar  exe 'normal kk0ifoo '
7063e2d1c8cSBram Moolenaar  set undolevels=100
7073e2d1c8cSBram Moolenaar  normal dd
7083e2d1c8cSBram Moolenaar  set undolevels=100
7093e2d1c8cSBram Moolenaar  exe 'normal ibar '
7103e2d1c8cSBram Moolenaar  set undolevels=100
7113e2d1c8cSBram Moolenaar  " encrypt the file using key 'foo2bar'
7123e2d1c8cSBram Moolenaar  call feedkeys("foo2bar\nfoo2bar\n")
7133e2d1c8cSBram Moolenaar  X
7143e2d1c8cSBram Moolenaar  write!
7153e2d1c8cSBram Moolenaar  bwipe!
7163e2d1c8cSBram Moolenaar
7173e2d1c8cSBram Moolenaar  call feedkeys("foo2bar\n")
7183e2d1c8cSBram Moolenaar  edit Xtestfile
7193e2d1c8cSBram Moolenaar  set key=
7203e2d1c8cSBram Moolenaar  call search('bar')
7213e2d1c8cSBram Moolenaar  call assert_equal('bar apr', getline('.'))
7223e2d1c8cSBram Moolenaar  normal u
7233e2d1c8cSBram Moolenaar  call assert_equal('apr', getline('.'))
7243e2d1c8cSBram Moolenaar  normal u
7253e2d1c8cSBram Moolenaar  call assert_equal('foo mar', getline('.'))
7263e2d1c8cSBram Moolenaar  normal u
7273e2d1c8cSBram Moolenaar  call assert_equal('mar', getline('.'))
7283e2d1c8cSBram Moolenaar
7293e2d1c8cSBram Moolenaar  bwipe!
7303e2d1c8cSBram Moolenaar  call delete('Xtestfile')
7313e2d1c8cSBram Moolenaar  let ufile = has('vms') ? '_un_Xtestfile' : '.Xtestfile.un~'
7323e2d1c8cSBram Moolenaar  call delete(ufile)
7333e2d1c8cSBram Moolenaar  set undofile& undolevels& cryptmethod&
7343e2d1c8cSBram Moolenaarendfunc
7353e2d1c8cSBram Moolenaar
736f4fcedc5SBram Moolenaar" Test for redoing with incrementing numbered registers
737f4fcedc5SBram Moolenaarfunc Test_redo_repeat_numbered_register()
738f4fcedc5SBram Moolenaar  new
739f4fcedc5SBram Moolenaar  for [i, v] in [[1, 'one'], [2, 'two'], [3, 'three'],
740f4fcedc5SBram Moolenaar        \ [4, 'four'], [5, 'five'], [6, 'six'],
741f4fcedc5SBram Moolenaar        \ [7, 'seven'], [8, 'eight'], [9, 'nine']]
742f4fcedc5SBram Moolenaar    exe 'let @' .. i .. '="' .. v .. '\n"'
743f4fcedc5SBram Moolenaar  endfor
744f4fcedc5SBram Moolenaar  call feedkeys('"1p.........', 'xt')
745f4fcedc5SBram Moolenaar  call assert_equal(['', 'one', 'two', 'three', 'four', 'five', 'six',
746f4fcedc5SBram Moolenaar        \ 'seven', 'eight', 'nine', 'nine'], getline(1, '$'))
747f4fcedc5SBram Moolenaar  bwipe!
748f4fcedc5SBram Moolenaarendfunc
749f4fcedc5SBram Moolenaar
7501f448d90SBram Moolenaar" Test for redo in insert mode using CTRL-O with multibyte characters
7511f448d90SBram Moolenaarfunc Test_redo_multibyte_in_insert_mode()
7521f448d90SBram Moolenaar  new
7531f448d90SBram Moolenaar  call feedkeys("a\<C-K>ft", 'xt')
7541f448d90SBram Moolenaar  call feedkeys("uiHe\<C-O>.llo", 'xt')
7551f448d90SBram Moolenaar  call assert_equal("He\ufb05llo", getline(1))
7561f448d90SBram Moolenaar  bwipe!
7571f448d90SBram Moolenaarendfunc
7581f448d90SBram Moolenaar
7593e2d1c8cSBram Moolenaar" vim: shiftwidth=2 sts=2 expandtab
760