Files
neovim/test/old/testdir/test_undo.vim
zeertzjq 44eae48b75 vim-patch:9.1.0893: No test that undofile format does not regress (#37193)
Problem:  No test that undofile format does not regress
Solution: include a sample undofile to make sure we are always able to
          read it

This is so, that we don't unintentionally change the undofile format and
make sure we can load an undo file that has been created by an older
Vim.

closes: vim/vim#16127

14382c8bc9

Convert the undo file in samples/ using method from #13973.

Co-authored-by: Christian Brabandt <cb@256bit.org>
(cherry picked from commit 94f7302e66)
2026-01-01 23:40:43 +00:00

916 lines
23 KiB
VimL

" Tests for the undo tree.
" Since this script is sourced we need to explicitly break changes up in
" undo-able pieces. Do that by setting 'undolevels'.
" Also tests :earlier and :later.
source check.vim
source screendump.vim
func Test_undotree()
new
normal! Aabc
set ul=100
let d = undotree()
call assert_equal(1, d.seq_last)
call assert_equal(1, d.seq_cur)
call assert_equal(0, d.save_last)
call assert_equal(0, d.save_cur)
call assert_equal(1, len(d.entries))
call assert_equal(1, d.entries[0].newhead)
call assert_equal(1, d.entries[0].seq)
call assert_true(d.entries[0].time <= d.time_cur)
normal! Adef
set ul=100
let d = undotree()
call assert_equal(2, d.seq_last)
call assert_equal(2, d.seq_cur)
call assert_equal(0, d.save_last)
call assert_equal(0, d.save_cur)
call assert_equal(2, len(d.entries))
call assert_equal(1, d.entries[0].seq)
call assert_equal(1, d.entries[1].newhead)
call assert_equal(2, d.entries[1].seq)
call assert_true(d.entries[1].time <= d.time_cur)
undo
set ul=100
let d = undotree()
call assert_equal(2, d.seq_last)
call assert_equal(1, d.seq_cur)
call assert_equal(0, d.save_last)
call assert_equal(0, d.save_cur)
call assert_equal(2, len(d.entries))
call assert_equal(1, d.entries[0].seq)
call assert_equal(1, d.entries[1].curhead)
call assert_equal(1, d.entries[1].newhead)
call assert_equal(2, d.entries[1].seq)
call assert_true(d.entries[1].time == d.time_cur)
normal! Aghi
set ul=100
let d = undotree()
call assert_equal(3, d.seq_last)
call assert_equal(3, d.seq_cur)
call assert_equal(0, d.save_last)
call assert_equal(0, d.save_cur)
call assert_equal(2, len(d.entries))
call assert_equal(1, d.entries[0].seq)
call assert_equal(2, d.entries[1].alt[0].seq)
call assert_equal(1, d.entries[1].newhead)
call assert_equal(3, d.entries[1].seq)
call assert_true(d.entries[1].time <= d.time_cur)
undo
set ul=100
let d = undotree()
call assert_equal(3, d.seq_last)
call assert_equal(1, d.seq_cur)
call assert_equal(0, d.save_last)
call assert_equal(0, d.save_cur)
call assert_equal(2, len(d.entries))
call assert_equal(1, d.entries[0].seq)
call assert_equal(2, d.entries[1].alt[0].seq)
call assert_equal(1, d.entries[1].curhead)
call assert_equal(1, d.entries[1].newhead)
call assert_equal(3, d.entries[1].seq)
call assert_true(d.entries[1].time == d.time_cur)
w! Xtest
let d = undotree()
call assert_equal(1, d.save_cur)
call assert_equal(1, d.save_last)
call delete('Xtest')
bwipe! Xtest
endfunc
func FillBuffer()
for i in range(1,13)
put=i
" Set 'undolevels' to split undo.
exe "setg ul=" . &g:ul
endfor
endfunc
func Test_undotree_bufnr()
new
let buf1 = bufnr()
normal! Aabc
set ul=100
" Save undo tree without bufnr as ground truth for buffer 1
let d1 = undotree()
new
let buf2 = bufnr()
normal! Adef
set ul=100
normal! Aghi
set ul=100
" Save undo tree without bufnr as ground truth for buffer 2
let d2 = undotree()
" Check undotree() with bufnr argument
let d = undotree(buf1)
call assert_equal(d1, d)
call assert_notequal(d2, d)
let d = undotree(buf2)
call assert_notequal(d1, d)
call assert_equal(d2, d)
" Switch buffers and check again
wincmd p
let d = undotree(buf1)
call assert_equal(d1, d)
let d = undotree(buf2)
call assert_notequal(d1, d)
call assert_equal(d2, d)
" error cases
call assert_fails('call undotree(-1)', 'E158:')
call assert_fails('call undotree("nosuchbuf")', 'E158:')
" after creating a buffer nosuchbuf, undotree('nosuchbuf') should
" not error out
new nosuchbuf
let d = {'seq_last': 0, 'entries': [], 'time_cur': 0, 'save_last': 0, 'synced': 1, 'save_cur': 0, 'seq_cur': 0}
call assert_equal(d, undotree("nosuchbuf"))
" clean up
bw nosuchbuf
" Drop created windows
set ul&
new
only!
endfunc
func Test_global_local_undolevels()
new one
set undolevels=5
call FillBuffer()
" will only undo the last 5 changes, end up with 13 - (5 + 1) = 7 lines
earlier 10
call assert_equal(5, &g:undolevels)
call assert_equal(-123456, &l:undolevels)
call assert_equal('7', getline('$'))
new two
setlocal undolevels=2
call FillBuffer()
" will only undo the last 2 changes, end up with 13 - (2 + 1) = 10 lines
earlier 10
call assert_equal(5, &g:undolevels)
call assert_equal(2, &l:undolevels)
call assert_equal('10', getline('$'))
setlocal ul=10
call assert_equal(5, &g:undolevels)
call assert_equal(10, &l:undolevels)
" Setting local value in "two" must not change local value in "one"
wincmd p
call assert_equal(5, &g:undolevels)
call assert_equal(-123456, &l:undolevels)
new three
setglobal ul=50
call assert_equal(50, &g:undolevels)
call assert_equal(-123456, &l:undolevels)
" Resetting the local 'undolevels' value to use the global value
setlocal undolevels=5
"setlocal undolevels<
set undolevels<
call assert_equal(-123456, &l:undolevels)
" Drop created windows
set ul&
new
only!
endfunc
func BackOne(expected)
call feedkeys('g-', 'xt')
call assert_equal(a:expected, getline(1))
endfunc
func Test_undo_del_chars()
throw 'Skipped: Nvim does not support test_settime()'
" Setup a buffer without creating undo entries
new
set ul=-1
call setline(1, ['123-456'])
set ul=100
1
call test_settime(100)
" Delete three characters and undo with g-
call feedkeys('x', 'xt')
call feedkeys('x', 'xt')
call feedkeys('x', 'xt')
call assert_equal('-456', getline(1))
call BackOne('3-456')
call BackOne('23-456')
call BackOne('123-456')
call assert_fails("BackOne('123-456')")
:" Delete three other characters and go back in time with g-
call feedkeys('$x', 'xt')
call feedkeys('x', 'xt')
call feedkeys('x', 'xt')
call assert_equal('123-', getline(1))
call test_settime(101)
call BackOne('123-4')
call BackOne('123-45')
" skips '123-456' because it's older
call BackOne('-456')
call BackOne('3-456')
call BackOne('23-456')
call BackOne('123-456')
call assert_fails("BackOne('123-456')")
normal 10g+
call assert_equal('123-', getline(1))
:" Jump two seconds and go some seconds forward and backward
call test_settime(103)
call feedkeys("Aa\<Esc>", 'xt')
call feedkeys("Ab\<Esc>", 'xt')
call feedkeys("Ac\<Esc>", 'xt')
call assert_equal('123-abc', getline(1))
earlier 1s
call assert_equal('123-', getline(1))
earlier 3s
call assert_equal('123-456', getline(1))
later 1s
call assert_equal('123-', getline(1))
later 1h
call assert_equal('123-abc', getline(1))
close!
endfunc
func Test_undolist()
new
set ul=100
let a = execute('undolist')
call assert_equal("\nNothing to undo", a)
" 1 leaf (2 changes).
call feedkeys('achange1', 'xt')
call feedkeys('achange2', 'xt')
let a = execute('undolist')
call assert_match("^\nnumber changes when *saved\n *2 *2 .*$", a)
" 2 leaves.
call feedkeys('u', 'xt')
call feedkeys('achange3\<Esc>', 'xt')
let a = execute('undolist')
call assert_match("^\nnumber changes when *saved\n *2 *2 *.*\n *3 *2 .*$", a)
close!
endfunc
func Test_U_command()
new
set ul=100
call feedkeys("achange1\<Esc>", 'xt')
call feedkeys("achange2\<Esc>", 'xt')
norm! U
call assert_equal('', getline(1))
norm! U
call assert_equal('change1change2', getline(1))
close!
endfunc
func Test_undojoin()
new
call feedkeys("Goaaaa\<Esc>", 'xt')
call feedkeys("obbbb\<Esc>", 'xt')
call assert_equal(['aaaa', 'bbbb'], getline(2, '$'))
call feedkeys("u", 'xt')
call assert_equal(['aaaa'], getline(2, '$'))
call feedkeys("obbbb\<Esc>", 'xt')
undojoin
" Note: next change must not be as if typed
call feedkeys("occcc\<Esc>", 'x')
call assert_equal(['aaaa', 'bbbb', 'cccc'], getline(2, '$'))
call feedkeys("u", 'xt')
call assert_equal(['aaaa'], getline(2, '$'))
bwipe!
endfunc
func Test_undojoin_redo()
new
call setline(1, ['first line', 'second line'])
call feedkeys("ixx\<Esc>", 'xt')
call feedkeys(":undojoin | redo\<CR>", 'xt')
call assert_equal('xxfirst line', getline(1))
call assert_equal('second line', getline(2))
bwipe!
endfunc
" undojoin not allowed after undo
func Test_undojoin_after_undo()
new
call feedkeys("ixx\<Esc>u", 'xt')
call assert_fails(':undojoin', 'E790:')
bwipe!
endfunc
" undojoin is a noop when no change yet, or when 'undolevels' is negative
func Test_undojoin_noop()
new
call feedkeys(":undojoin\<CR>", 'xt')
call assert_equal([''], getline(1, '$'))
setlocal undolevels=-1
call feedkeys("ixx\<Esc>u", 'xt')
call feedkeys(":undojoin\<CR>", 'xt')
call assert_equal(['xx'], getline(1, '$'))
bwipe!
endfunc
func Test_undo_write()
call delete('Xtest')
split Xtest
call feedkeys("ione one one\<Esc>", 'xt')
w!
call feedkeys("otwo\<Esc>", 'xt')
call feedkeys("otwo\<Esc>", 'xt')
w
call feedkeys("othree\<Esc>", 'xt')
call assert_equal(['one one one', 'two', 'two', 'three'], getline(1, '$'))
earlier 1f
call assert_equal(['one one one', 'two', 'two'], getline(1, '$'))
earlier 1f
call assert_equal(['one one one'], getline(1, '$'))
earlier 1f
call assert_equal([''], getline(1, '$'))
later 1f
call assert_equal(['one one one'], getline(1, '$'))
later 1f
call assert_equal(['one one one', 'two', 'two'], getline(1, '$'))
later 1f
call assert_equal(['one one one', 'two', 'two', 'three'], getline(1, '$'))
close!
call delete('Xtest')
bwipe! Xtest
call assert_fails('earlier xyz', 'E475:')
endfunc
func Test_insert_expr()
new
" calling setline() triggers undo sync
call feedkeys("oa\<Esc>", 'xt')
call feedkeys("ob\<Esc>", 'xt')
set ul=100
call feedkeys("o1\<Esc>a2\<C-R>=setline('.','1234')\<CR>\<CR>\<Esc>", 'x')
call assert_equal(['a', 'b', '120', '34'], getline(2, '$'))
call feedkeys("u", 'x')
call assert_equal(['a', 'b', '12'], getline(2, '$'))
call feedkeys("u", 'x')
call assert_equal(['a', 'b'], getline(2, '$'))
call feedkeys("oc\<Esc>", 'xt')
set ul=100
call feedkeys("o1\<Esc>a2\<C-R>=setline('.','1234')\<CR>\<CR>\<Esc>", 'x')
call assert_equal(['a', 'b', 'c', '120', '34'], getline(2, '$'))
call feedkeys("u", 'x')
call assert_equal(['a', 'b', 'c', '12'], getline(2, '$'))
call feedkeys("od\<Esc>", 'xt')
set ul=100
call feedkeys("o1\<Esc>a2\<C-R>=string(123)\<CR>\<Esc>", 'x')
call assert_equal(['a', 'b', 'c', '12', 'd', '12123'], getline(2, '$'))
call feedkeys("u", 'x')
call assert_equal(['a', 'b', 'c', '12', 'd'], getline(2, '$'))
close!
endfunc
func Test_undofile_earlier()
throw 'Skipped: Nvim does not support test_settime()'
if has('win32')
" FIXME: This test is flaky on MS-Windows.
let g:test_is_flaky = 1
endif
" Issue #1254
" create undofile with timestamps older than Vim startup time.
let t0 = localtime() - 43200
call test_settime(t0)
new XfileEarlier
call feedkeys("ione\<Esc>", 'xt')
set ul=100
call test_settime(t0 + 1)
call feedkeys("otwo\<Esc>", 'xt')
set ul=100
call test_settime(t0 + 2)
call feedkeys("othree\<Esc>", 'xt')
set ul=100
w
wundo Xundofile
bwipe!
" restore normal timestamps.
call test_settime(0)
new XfileEarlier
rundo Xundofile
earlier 1d
call assert_equal('', getline(1))
bwipe!
call delete('XfileEarlier')
call delete('Xundofile')
endfunc
func Test_wundo_errors()
new
call setline(1, 'hello')
call assert_fails('wundo! Xdoesnotexist/Xundofile', 'E828:')
bwipe!
endfunc
" Check that reading a truncated undo file doesn't hang.
func Test_undofile_truncated()
new
call setline(1, 'hello')
set ul=100
wundo Xundofile
let contents = readfile('Xundofile', 'B')
" try several sizes
for size in range(20, 500, 33)
call writefile(contents[0:size], 'Xundofile')
call assert_fails('rundo Xundofile', 'E825:')
endfor
bwipe!
call delete('Xundofile')
endfunc
func Test_rundo_errors()
call assert_fails('rundo XfileDoesNotExist', 'E822:')
call writefile(['abc'], 'Xundofile')
call assert_fails('rundo Xundofile', 'E823:')
call delete('Xundofile')
endfunc
func Test_undofile_next()
set undofile
new Xfoo.txt
execute "norm ix\<c-g>uy\<c-g>uz\<Esc>"
write
bwipe
next Xfoo.txt
call assert_equal('xyz', getline(1))
silent undo
call assert_equal('xy', getline(1))
silent undo
call assert_equal('x', getline(1))
bwipe!
call delete('Xfoo.txt')
call delete('.Xfoo.txt.un~')
set undofile&
endfunc
" Test for undo working properly when executing commands from a register.
" Also test this in an empty buffer.
func Test_cmd_in_reg_undo()
enew!
let @a = "Ox\<Esc>jAy\<Esc>kdd"
edit +/^$ test_undo.vim
normal @au
call assert_equal(0, &modified)
return
new
normal @au
call assert_equal(0, &modified)
only!
let @a = ''
endfunc
" This used to cause an illegal memory access
func Test_undo_append()
new
call feedkeys("axx\<Esc>v", 'xt')
undo
norm o
quit
endfunc
func Test_undo_0()
new
set ul=100
normal i1
undo
normal i2
undo
normal i3
undo 0
let d = undotree()
call assert_equal('', getline(1))
call assert_equal(0, d.seq_cur)
redo
let d = undotree()
call assert_equal('3', getline(1))
call assert_equal(3, d.seq_cur)
undo 2
undo 0
let d = undotree()
call assert_equal('', getline(1))
call assert_equal(0, d.seq_cur)
redo
let d = undotree()
call assert_equal('2', getline(1))
call assert_equal(2, d.seq_cur)
undo 1
undo 0
let d = undotree()
call assert_equal('', getline(1))
call assert_equal(0, d.seq_cur)
redo
let d = undotree()
call assert_equal('1', getline(1))
call assert_equal(1, d.seq_cur)
bwipe!
endfunc
" undo or redo are noop if there is nothing to undo or redo
func Test_undo_redo_noop()
new
call assert_fails('undo 2', 'E830:')
message clear
undo
let messages = split(execute('message'), "\n")
call assert_equal('Already at oldest change', messages[-1])
message clear
redo
let messages = split(execute('message'), "\n")
call assert_equal('Already at newest change', messages[-1])
bwipe!
endfunc
func Test_redo_empty_line()
new
exe "norm\x16r\x160"
exe "norm."
bwipe!
endfunc
funct Test_undofile()
" Test undofile() without setting 'undodir'.
if has('persistent_undo')
call assert_equal(fnamemodify('.Xundofoo.un~', ':p'), undofile('Xundofoo'))
else
call assert_equal('', undofile('Xundofoo'))
endif
call assert_equal('', undofile(''))
" Test undofile() with 'undodir' set to an existing directory.
call mkdir('Xundodir')
set undodir=Xundodir
let cwd = getcwd()
if has('win32')
" Replace windows drive such as C:... into C%...
let cwd = substitute(cwd, '^\([a-zA-Z]\):', '\1%', 'g')
endif
let cwd = substitute(cwd . '/Xundofoo', '/', '%', 'g')
if has('persistent_undo')
call assert_equal('Xundodir/' . cwd, undofile('Xundofoo'))
else
call assert_equal('', undofile('Xundofoo'))
endif
call assert_equal('', undofile(''))
call delete('Xundodir', 'd')
" Test undofile() with 'undodir' set to a non-existing directory.
" call assert_equal('', 'Xundofoo'->undofile())
if isdirectory('/tmp')
set undodir=/tmp
if has('osx')
call assert_equal('/tmp/%private%tmp%file', undofile('///tmp/file'))
else
call assert_equal('/tmp/%tmp%file', undofile('///tmp/file'))
endif
endif
set undodir&
endfunc
" Tests for the undo file
" Explicitly break changes up in undo-able pieces by setting 'undolevels'.
func Test_undofile_2()
set undolevels=100 undofile
edit Xtestfile
call append(0, 'this is one line')
call cursor(1, 1)
" first a simple one-line change.
set undolevels=100
s/one/ONE/
set undolevels=100
write
bwipe!
edit Xtestfile
undo
call assert_equal('this is one line', getline(1))
" change in original file fails check
set noundofile
edit! Xtestfile
s/line/Line/
write
set undofile
bwipe!
edit Xtestfile
undo
call assert_equal('this is ONE Line', getline(1))
" add 10 lines, delete 6 lines, undo 3
set undofile
call setbufline('%', 1, ['one', 'two', 'three', 'four', 'five', 'six',
\ 'seven', 'eight', 'nine', 'ten'])
set undolevels=100
normal 3Gdd
set undolevels=100
normal dd
set undolevels=100
normal dd
set undolevels=100
normal dd
set undolevels=100
normal dd
set undolevels=100
normal dd
set undolevels=100
write
bwipe!
edit Xtestfile
normal uuu
call assert_equal(['one', 'two', 'six', 'seven', 'eight', 'nine', 'ten'],
\ getline(1, '$'))
" Test that reading the undofiles when setting undofile works
set noundofile undolevels=0
exe "normal i\n"
undo
edit! Xtestfile
set undofile undolevels=100
normal uuuuuu
call assert_equal(['one', 'two', 'three', 'four', 'five', 'six', 'seven',
\ 'eight', 'nine', 'ten'], getline(1, '$'))
bwipe!
call delete('Xtestfile')
let ufile = has('vms') ? '_un_Xtestfile' : '.Xtestfile.un~'
call delete(ufile)
set undofile& undolevels&
endfunc
" Test 'undofile' using a file encrypted with 'zip' crypt method
func Test_undofile_cryptmethod_zip()
throw 'skipped: Nvim does not support cryptmethod'
edit Xtestfile
set undofile cryptmethod=zip
call append(0, ['monday', 'tuesday', 'wednesday', 'thursday', 'friday'])
call cursor(5, 1)
set undolevels=100
normal kkkdd
set undolevels=100
normal dd
set undolevels=100
normal dd
set undolevels=100
" encrypt the file using key 'foobar'
call feedkeys("foobar\nfoobar\n")
X
write!
bwipe!
call feedkeys("foobar\n")
edit Xtestfile
set key=
normal uu
call assert_equal(['monday', 'wednesday', 'thursday', 'friday', ''],
\ getline(1, '$'))
bwipe!
call delete('Xtestfile')
let ufile = has('vms') ? '_un_Xtestfile' : '.Xtestfile.un~'
call delete(ufile)
set undofile& undolevels& cryptmethod&
endfunc
" Test 'undofile' using a file encrypted with 'blowfish' crypt method
func Test_undofile_cryptmethod_blowfish()
throw 'skipped: Nvim does not support cryptmethod'
edit Xtestfile
set undofile cryptmethod=blowfish
call append(0, ['jan', 'feb', 'mar', 'apr', 'jun'])
call cursor(5, 1)
set undolevels=100
exe 'normal kk0ifoo '
set undolevels=100
normal dd
set undolevels=100
exe 'normal ibar '
set undolevels=100
" encrypt the file using key 'foobar'
call feedkeys("foobar\nfoobar\n")
X
write!
bwipe!
call feedkeys("foobar\n")
edit Xtestfile
set key=
call search('bar')
call assert_equal('bar apr', getline('.'))
undo
call assert_equal('apr', getline('.'))
undo
call assert_equal('foo mar', getline('.'))
undo
call assert_equal('mar', getline('.'))
bwipe!
call delete('Xtestfile')
let ufile = has('vms') ? '_un_Xtestfile' : '.Xtestfile.un~'
call delete(ufile)
set undofile& undolevels& cryptmethod&
endfunc
" Test 'undofile' using a file encrypted with 'blowfish2' crypt method
func Test_undofile_cryptmethod_blowfish2()
throw 'skipped: Nvim does not support cryptmethod'
edit Xtestfile
set undofile cryptmethod=blowfish2
call append(0, ['jan', 'feb', 'mar', 'apr', 'jun'])
call cursor(5, 1)
set undolevels=100
exe 'normal kk0ifoo '
set undolevels=100
normal dd
set undolevels=100
exe 'normal ibar '
set undolevels=100
" encrypt the file using key 'foo2bar'
call feedkeys("foo2bar\nfoo2bar\n")
X
write!
bwipe!
call feedkeys("foo2bar\n")
edit Xtestfile
set key=
call search('bar')
call assert_equal('bar apr', getline('.'))
normal u
call assert_equal('apr', getline('.'))
normal u
call assert_equal('foo mar', getline('.'))
normal u
call assert_equal('mar', getline('.'))
bwipe!
call delete('Xtestfile')
let ufile = has('vms') ? '_un_Xtestfile' : '.Xtestfile.un~'
call delete(ufile)
set undofile& undolevels& cryptmethod&
endfunc
" Test for redoing with incrementing numbered registers
func Test_redo_repeat_numbered_register()
new
for [i, v] in [[1, 'one'], [2, 'two'], [3, 'three'],
\ [4, 'four'], [5, 'five'], [6, 'six'],
\ [7, 'seven'], [8, 'eight'], [9, 'nine']]
exe 'let @' .. i .. '="' .. v .. '\n"'
endfor
call feedkeys('"1p.........', 'xt')
call assert_equal(['', 'one', 'two', 'three', 'four', 'five', 'six',
\ 'seven', 'eight', 'nine', 'nine'], getline(1, '$'))
bwipe!
endfunc
" Test for redo in insert mode using CTRL-O with multibyte characters
func Test_redo_multibyte_in_insert_mode()
new
call feedkeys("a\<C-K>ft", 'xt')
call feedkeys("uiHe\<C-O>.llo", 'xt')
call assert_equal("He\ufb05llo", getline(1))
bwipe!
endfunc
func Test_undo_mark()
new
" The undo is applied to the only line.
call setline(1, 'hello')
call feedkeys("ggyiw$p", 'xt')
undo
call assert_equal([0, 1, 1, 0], getpos("'["))
call assert_equal([0, 1, 1, 0], getpos("']"))
" The undo removes the last line.
call feedkeys("Goaaaa\<Esc>", 'xt')
call feedkeys("obbbb\<Esc>", 'xt')
undo
call assert_equal([0, 2, 1, 0], getpos("'["))
call assert_equal([0, 2, 1, 0], getpos("']"))
bwipe!
endfunc
func Test_undo_after_write()
" use a terminal to make undo work like when text is typed
CheckRunVimInTerminal
let lines =<< trim END
edit Xtestfile.txt
set undolevels=100 undofile
imap . <Cmd>write<CR>
write
END
call writefile(lines, 'Xtest_undo_after_write', 'D')
let buf = RunVimInTerminal('-S Xtest_undo_after_write', #{rows: 6})
call term_sendkeys(buf, "Otest.\<CR>boo!!!\<Esc>")
sleep 100m
call term_sendkeys(buf, "u")
call VerifyScreenDump(buf, 'Test_undo_after_write_1', {})
call term_sendkeys(buf, "u")
call VerifyScreenDump(buf, 'Test_undo_after_write_2', {})
call StopVimInTerminal(buf)
call delete('Xtestfile.txt')
call delete('.Xtestfile.txt.un~')
endfunc
func Test_undo_range_normal()
new
call setline(1, ['asa', 'bsb'])
let &l:undolevels = &l:undolevels
%normal dfs
call assert_equal(['a', 'b'], getline(1, '$'))
undo
call assert_equal(['asa', 'bsb'], getline(1, '$'))
bwipe!
endfunc
func Test_load_existing_undofile()
CheckFeature persistent_undo
sp samples/test_undo.txt
let mess=execute(':verbose rundo samples/test_undo.txt.undo')
call assert_match('Finished reading undo file', mess)
call assert_equal(['one', 'two', 'three'], getline(1, '$'))
norm! u
call assert_equal(['one', 'two'], getline(1, '$'))
norm! u
call assert_equal(['one'], getline(1, '$'))
norm! u
call assert_equal([''], getline(1, '$'))
let mess = execute(':norm! u')
call assert_equal([''], getline(1, '$'))
call assert_match('Already at oldest change', mess)
exe ":norm! \<c-r>"
call assert_equal(['one'], getline(1, '$'))
exe ":norm! \<c-r>"
call assert_equal(['one', 'two'], getline(1, '$'))
exe ":norm! \<c-r>"
call assert_equal(['one', 'two', 'three'], getline(1, '$'))
let mess = execute(":norm! \<c-r>")
call assert_equal(['one', 'two', 'three'], getline(1, '$'))
call assert_match('Already at newest change', mess)
bw!
endfunc
" vim: shiftwidth=2 sts=2 expandtab