xref: /vim-8.2.3635/src/testdir/test_swap.vim (revision 8b0e62c9)
1430dc5d3SBram Moolenaar" Tests for the swap feature
2430dc5d3SBram Moolenaar
3d36ef573SBram Moolenaarsource check.vim
407282f01SBram Moolenaarsource shared.vim
5b654103aSBram Moolenaarsource term_util.vim
607282f01SBram Moolenaar
7110bd609SBram Moolenaarfunc s:swapname()
8110bd609SBram Moolenaar  return trim(execute('swapname'))
9110bd609SBram Moolenaarendfunc
10110bd609SBram Moolenaar
11ffe010faSBram Moolenaar" Tests for 'directory' option.
12ffe010faSBram Moolenaarfunc Test_swap_directory()
136d91bcb4SBram Moolenaar  CheckUnix
146d91bcb4SBram Moolenaar
15ffe010faSBram Moolenaar  let content = ['start of testfile',
16ffe010faSBram Moolenaar	      \ 'line 2 Abcdefghij',
17ffe010faSBram Moolenaar	      \ 'line 3 Abcdefghij',
18ffe010faSBram Moolenaar	      \ 'end of testfile']
19ffe010faSBram Moolenaar  call writefile(content, 'Xtest1')
20ffe010faSBram Moolenaar
21ffe010faSBram Moolenaar  "  '.', swap file in the same directory as file
22ffe010faSBram Moolenaar  set dir=.,~
23ffe010faSBram Moolenaar
24ffe010faSBram Moolenaar  " Verify that the swap file doesn't exist in the current directory
25ffe010faSBram Moolenaar  call assert_equal([], glob(".Xtest1*.swp", 1, 1, 1))
26ffe010faSBram Moolenaar  edit Xtest1
27110bd609SBram Moolenaar  let swfname = s:swapname()
28ffe010faSBram Moolenaar  call assert_equal([swfname], glob(swfname, 1, 1, 1))
29ffe010faSBram Moolenaar
30ffe010faSBram Moolenaar  " './dir', swap file in a directory relative to the file
31ffe010faSBram Moolenaar  set dir=./Xtest2,.,~
32ffe010faSBram Moolenaar
33ffe010faSBram Moolenaar  call mkdir("Xtest2")
34ffe010faSBram Moolenaar  edit Xtest1
35ffe010faSBram Moolenaar  call assert_equal([], glob(swfname, 1, 1, 1))
36ffe010faSBram Moolenaar  let swfname = "Xtest2/Xtest1.swp"
37110bd609SBram Moolenaar  call assert_equal(swfname, s:swapname())
38ffe010faSBram Moolenaar  call assert_equal([swfname], glob("Xtest2/*", 1, 1, 1))
39ffe010faSBram Moolenaar
40ffe010faSBram Moolenaar  " 'dir', swap file in directory relative to the current dir
41ffe010faSBram Moolenaar  set dir=Xtest.je,~
42ffe010faSBram Moolenaar
43ffe010faSBram Moolenaar  call mkdir("Xtest.je")
44ffe010faSBram Moolenaar  call writefile(content, 'Xtest2/Xtest3')
45ffe010faSBram Moolenaar  edit Xtest2/Xtest3
46ffe010faSBram Moolenaar  call assert_equal(["Xtest2/Xtest3"], glob("Xtest2/*", 1, 1, 1))
47ffe010faSBram Moolenaar  let swfname = "Xtest.je/Xtest3.swp"
48110bd609SBram Moolenaar  call assert_equal(swfname, s:swapname())
49ffe010faSBram Moolenaar  call assert_equal([swfname], glob("Xtest.je/*", 1, 1, 1))
50ffe010faSBram Moolenaar
51ffe010faSBram Moolenaar  set dir&
52ffe010faSBram Moolenaar  call delete("Xtest1")
53ffe010faSBram Moolenaar  call delete("Xtest2", "rf")
54ffe010faSBram Moolenaar  call delete("Xtest.je", "rf")
55ffe010faSBram Moolenaarendfunc
565a73e0caSBram Moolenaar
575a73e0caSBram Moolenaarfunc Test_swap_group()
586d91bcb4SBram Moolenaar  CheckUnix
596d91bcb4SBram Moolenaar
605a73e0caSBram Moolenaar  let groups = split(system('groups'))
615a73e0caSBram Moolenaar  if len(groups) <= 1
62ad7dac85SBram Moolenaar    throw 'Skipped: need at least two groups, got ' . string(groups)
635a73e0caSBram Moolenaar  endif
64430dc5d3SBram Moolenaar
655842a748SBram Moolenaar  try
665a73e0caSBram Moolenaar    call delete('Xtest')
675a73e0caSBram Moolenaar    split Xtest
685a73e0caSBram Moolenaar    call setline(1, 'just some text')
695a73e0caSBram Moolenaar    wq
705a73e0caSBram Moolenaar    if system('ls -l Xtest') !~ ' ' . groups[0] . ' \d'
715a73e0caSBram Moolenaar      throw 'Skipped: test file does not have the first group'
725a73e0caSBram Moolenaar    else
735a73e0caSBram Moolenaar      silent !chmod 640 Xtest
745a73e0caSBram Moolenaar      call system('chgrp ' . groups[1] . ' Xtest')
755a73e0caSBram Moolenaar      if system('ls -l Xtest') !~ ' ' . groups[1] . ' \d'
765a73e0caSBram Moolenaar	throw 'Skipped: cannot set second group on test file'
775a73e0caSBram Moolenaar      else
785a73e0caSBram Moolenaar	split Xtest
79110bd609SBram Moolenaar	let swapname = s:swapname()
805a73e0caSBram Moolenaar	call assert_match('Xtest', swapname)
815a73e0caSBram Moolenaar	" Group of swapfile must now match original file.
825a73e0caSBram Moolenaar	call assert_match(' ' . groups[1] . ' \d', system('ls -l ' . swapname))
83430dc5d3SBram Moolenaar
845a73e0caSBram Moolenaar	bwipe!
855a73e0caSBram Moolenaar      endif
865a73e0caSBram Moolenaar    endif
875842a748SBram Moolenaar  finally
885a73e0caSBram Moolenaar    call delete('Xtest')
895842a748SBram Moolenaar  endtry
90430dc5d3SBram Moolenaarendfunc
918c3169c5SBram Moolenaar
928c3169c5SBram Moolenaarfunc Test_missing_dir()
938c3169c5SBram Moolenaar  call mkdir('Xswapdir')
948c3169c5SBram Moolenaar  exe 'set directory=' . getcwd() . '/Xswapdir'
958c3169c5SBram Moolenaar
968c3169c5SBram Moolenaar  call assert_equal('', glob('foo'))
978c3169c5SBram Moolenaar  call assert_equal('', glob('bar'))
988c3169c5SBram Moolenaar  edit foo/x.txt
998c3169c5SBram Moolenaar  " This should not give a warning for an existing swap file.
1008c3169c5SBram Moolenaar  split bar/x.txt
1018c3169c5SBram Moolenaar  only
1028c3169c5SBram Moolenaar
103e3d06545SBram Moolenaar  " Delete the buffer so that swap file is removed before we try to delete the
104e3d06545SBram Moolenaar  " directory.  That fails on MS-Windows.
105e3d06545SBram Moolenaar  %bdelete!
1068c3169c5SBram Moolenaar  set directory&
1078c3169c5SBram Moolenaar  call delete('Xswapdir', 'rf')
1088c3169c5SBram Moolenaarendfunc
10900f123a5SBram Moolenaar
11000f123a5SBram Moolenaarfunc Test_swapinfo()
11100f123a5SBram Moolenaar  new Xswapinfo
11200f123a5SBram Moolenaar  call setline(1, ['one', 'two', 'three'])
11300f123a5SBram Moolenaar  w
114110bd609SBram Moolenaar  let fname = s:swapname()
11500f123a5SBram Moolenaar  call assert_match('Xswapinfo', fname)
116f6ed61e1SBram Moolenaar  let info = fname->swapinfo()
1174c5765bcSBram Moolenaar
1184c5765bcSBram Moolenaar  let ver = printf('VIM %d.%d', v:version / 100, v:version % 100)
1194c5765bcSBram Moolenaar  call assert_equal(ver, info.version)
1204c5765bcSBram Moolenaar
12100f123a5SBram Moolenaar  call assert_match('\w', info.user)
1224c5765bcSBram Moolenaar  " host name is truncated to 39 bytes in the swap file
1234c5765bcSBram Moolenaar  call assert_equal(hostname()[:38], info.host)
12400f123a5SBram Moolenaar  call assert_match('Xswapinfo', info.fname)
12547ad5656SBram Moolenaar  call assert_match(0, info.dirty)
12600f123a5SBram Moolenaar  call assert_equal(getpid(), info.pid)
12700f123a5SBram Moolenaar  call assert_match('^\d*$', info.mtime)
12800f123a5SBram Moolenaar  if has_key(info, 'inode')
12900f123a5SBram Moolenaar    call assert_match('\d', info.inode)
13000f123a5SBram Moolenaar  endif
13100f123a5SBram Moolenaar  bwipe!
13200f123a5SBram Moolenaar  call delete(fname)
13300f123a5SBram Moolenaar  call delete('Xswapinfo')
13400f123a5SBram Moolenaar
13500f123a5SBram Moolenaar  let info = swapinfo('doesnotexist')
13600f123a5SBram Moolenaar  call assert_equal('Cannot open file', info.error)
13700f123a5SBram Moolenaar
13800f123a5SBram Moolenaar  call writefile(['burp'], 'Xnotaswapfile')
13900f123a5SBram Moolenaar  let info = swapinfo('Xnotaswapfile')
14000f123a5SBram Moolenaar  call assert_equal('Cannot read file', info.error)
14100f123a5SBram Moolenaar  call delete('Xnotaswapfile')
14200f123a5SBram Moolenaar
14300f123a5SBram Moolenaar  call writefile([repeat('x', 10000)], 'Xnotaswapfile')
14400f123a5SBram Moolenaar  let info = swapinfo('Xnotaswapfile')
14547ad5656SBram Moolenaar  call assert_equal('Not a swap file', info.error)
14600f123a5SBram Moolenaar  call delete('Xnotaswapfile')
14700f123a5SBram Moolenaarendfunc
148110bd609SBram Moolenaar
149110bd609SBram Moolenaarfunc Test_swapname()
150110bd609SBram Moolenaar  edit Xtest1
151110bd609SBram Moolenaar  let expected = s:swapname()
152110bd609SBram Moolenaar  call assert_equal(expected, swapname('%'))
153110bd609SBram Moolenaar
154110bd609SBram Moolenaar  new Xtest2
155110bd609SBram Moolenaar  let buf = bufnr('%')
156110bd609SBram Moolenaar  let expected = s:swapname()
157110bd609SBram Moolenaar  wincmd p
158f6ed61e1SBram Moolenaar  call assert_equal(expected, buf->swapname())
159110bd609SBram Moolenaar
160110bd609SBram Moolenaar  new Xtest3
161110bd609SBram Moolenaar  setlocal noswapfile
162110bd609SBram Moolenaar  call assert_equal('', swapname('%'))
163110bd609SBram Moolenaar
164110bd609SBram Moolenaar  bwipe!
165110bd609SBram Moolenaar  call delete('Xtest1')
166110bd609SBram Moolenaar  call delete('Xtest2')
167110bd609SBram Moolenaar  call delete('Xtest3')
168110bd609SBram Moolenaarendfunc
16967cf86bfSBram Moolenaar
17067cf86bfSBram Moolenaarfunc Test_swapfile_delete()
17167cf86bfSBram Moolenaar  autocmd! SwapExists
17267cf86bfSBram Moolenaar  function s:swap_exists()
17367cf86bfSBram Moolenaar    let v:swapchoice = s:swap_choice
17467cf86bfSBram Moolenaar    let s:swapname = v:swapname
17567cf86bfSBram Moolenaar    let s:filename = expand('<afile>')
17667cf86bfSBram Moolenaar  endfunc
17767cf86bfSBram Moolenaar  augroup test_swapfile_delete
17867cf86bfSBram Moolenaar    autocmd!
17967cf86bfSBram Moolenaar    autocmd SwapExists * call s:swap_exists()
18067cf86bfSBram Moolenaar  augroup END
18167cf86bfSBram Moolenaar
18267cf86bfSBram Moolenaar
18367cf86bfSBram Moolenaar  " Create a valid swapfile by editing a file.
18467cf86bfSBram Moolenaar  split XswapfileText
18567cf86bfSBram Moolenaar  call setline(1, ['one', 'two', 'three'])
18667cf86bfSBram Moolenaar  write  " file is written, not modified
18767cf86bfSBram Moolenaar  " read the swapfile as a Blob
18867cf86bfSBram Moolenaar  let swapfile_name = swapname('%')
18967cf86bfSBram Moolenaar  let swapfile_bytes = readfile(swapfile_name, 'B')
19067cf86bfSBram Moolenaar
19167cf86bfSBram Moolenaar  " Close the file and recreate the swap file.
19267cf86bfSBram Moolenaar  " Now editing the file will run into the process still existing
19367cf86bfSBram Moolenaar  quit
19467cf86bfSBram Moolenaar  call writefile(swapfile_bytes, swapfile_name)
19567cf86bfSBram Moolenaar  let s:swap_choice = 'e'
19667cf86bfSBram Moolenaar  let s:swapname = ''
19767cf86bfSBram Moolenaar  split XswapfileText
19867cf86bfSBram Moolenaar  quit
199701df4ebSBram Moolenaar  call assert_equal(fnamemodify(swapfile_name, ':t'), fnamemodify(s:swapname, ':t'))
20067cf86bfSBram Moolenaar
20107282f01SBram Moolenaar  " This test won't work as root because root can successfully run kill(1, 0)
20207282f01SBram Moolenaar  if !IsRoot()
20367cf86bfSBram Moolenaar    " Write the swapfile with a modified PID, now it will be automatically
2046738fd20SBram Moolenaar    " deleted. Process 0x3fffffff most likely does not exist.
2056738fd20SBram Moolenaar    let swapfile_bytes[24:27] = 0zffffff3f
20667cf86bfSBram Moolenaar    call writefile(swapfile_bytes, swapfile_name)
20767cf86bfSBram Moolenaar    let s:swapname = ''
20867cf86bfSBram Moolenaar    split XswapfileText
20967cf86bfSBram Moolenaar    quit
21067cf86bfSBram Moolenaar    call assert_equal('', s:swapname)
21107282f01SBram Moolenaar  endif
21267cf86bfSBram Moolenaar
21367cf86bfSBram Moolenaar  " Now set the modified flag, the swap file will not be deleted
21467cf86bfSBram Moolenaar  let swapfile_bytes[28 + 80 + 899] = 0x55
21567cf86bfSBram Moolenaar  call writefile(swapfile_bytes, swapfile_name)
21667cf86bfSBram Moolenaar  let s:swapname = ''
21767cf86bfSBram Moolenaar  split XswapfileText
21867cf86bfSBram Moolenaar  quit
219701df4ebSBram Moolenaar  call assert_equal(fnamemodify(swapfile_name, ':t'), fnamemodify(s:swapname, ':t'))
22067cf86bfSBram Moolenaar
22167cf86bfSBram Moolenaar  call delete('XswapfileText')
22267cf86bfSBram Moolenaar  call delete(swapfile_name)
22367cf86bfSBram Moolenaar  augroup test_swapfile_delete
22467cf86bfSBram Moolenaar    autocmd!
22567cf86bfSBram Moolenaar  augroup END
22667cf86bfSBram Moolenaar  augroup! test_swapfile_delete
22767cf86bfSBram Moolenaarendfunc
22899499b1cSBram Moolenaar
22999499b1cSBram Moolenaarfunc Test_swap_recover()
23099499b1cSBram Moolenaar  autocmd! SwapExists
23199499b1cSBram Moolenaar  augroup test_swap_recover
23299499b1cSBram Moolenaar    autocmd!
23399499b1cSBram Moolenaar    autocmd SwapExists * let v:swapchoice = 'r'
23499499b1cSBram Moolenaar  augroup END
23599499b1cSBram Moolenaar
23699499b1cSBram Moolenaar
23799499b1cSBram Moolenaar  call mkdir('Xswap')
23899499b1cSBram Moolenaar  let $Xswap = 'foo'  " Check for issue #4369.
23999499b1cSBram Moolenaar  set dir=Xswap//
24099499b1cSBram Moolenaar  " Create a valid swapfile by editing a file.
24199499b1cSBram Moolenaar  split Xswap/text
24299499b1cSBram Moolenaar  call setline(1, ['one', 'two', 'three'])
24399499b1cSBram Moolenaar  write  " file is written, not modified
24499499b1cSBram Moolenaar  " read the swapfile as a Blob
24599499b1cSBram Moolenaar  let swapfile_name = swapname('%')
24699499b1cSBram Moolenaar  let swapfile_bytes = readfile(swapfile_name, 'B')
24799499b1cSBram Moolenaar
24899499b1cSBram Moolenaar  " Close the file and recreate the swap file.
24999499b1cSBram Moolenaar  quit
25099499b1cSBram Moolenaar  call writefile(swapfile_bytes, swapfile_name)
25199499b1cSBram Moolenaar  " Edit the file again. This triggers recovery.
25299499b1cSBram Moolenaar  try
25399499b1cSBram Moolenaar    split Xswap/text
25499499b1cSBram Moolenaar  catch
25599499b1cSBram Moolenaar    " E308 should be caught, not E305.
25699499b1cSBram Moolenaar    call assert_exception('E308:')  " Original file may have been changed
25799499b1cSBram Moolenaar  endtry
25899499b1cSBram Moolenaar  " The file should be recovered.
25999499b1cSBram Moolenaar  call assert_equal(['one', 'two', 'three'], getline(1, 3))
26099499b1cSBram Moolenaar  quit!
26199499b1cSBram Moolenaar
26299499b1cSBram Moolenaar  call delete('Xswap/text')
26399499b1cSBram Moolenaar  call delete(swapfile_name)
26499499b1cSBram Moolenaar  call delete('Xswap', 'd')
26599499b1cSBram Moolenaar  unlet $Xswap
26699499b1cSBram Moolenaar  set dir&
26799499b1cSBram Moolenaar  augroup test_swap_recover
26899499b1cSBram Moolenaar    autocmd!
26999499b1cSBram Moolenaar  augroup END
27099499b1cSBram Moolenaar  augroup! test_swap_recover
27199499b1cSBram Moolenaarendfunc
27299499b1cSBram Moolenaar
27399499b1cSBram Moolenaarfunc Test_swap_recover_ext()
27499499b1cSBram Moolenaar  autocmd! SwapExists
27599499b1cSBram Moolenaar  augroup test_swap_recover_ext
27699499b1cSBram Moolenaar    autocmd!
27799499b1cSBram Moolenaar    autocmd SwapExists * let v:swapchoice = 'r'
27899499b1cSBram Moolenaar  augroup END
27999499b1cSBram Moolenaar
28099499b1cSBram Moolenaar  " Create a valid swapfile by editing a file with a special extension.
28199499b1cSBram Moolenaar  split Xtest.scr
28299499b1cSBram Moolenaar  call setline(1, ['one', 'two', 'three'])
28399499b1cSBram Moolenaar  write  " file is written, not modified
28499499b1cSBram Moolenaar  write  " write again to make sure the swapfile is created
28599499b1cSBram Moolenaar  " read the swapfile as a Blob
28699499b1cSBram Moolenaar  let swapfile_name = swapname('%')
28799499b1cSBram Moolenaar  let swapfile_bytes = readfile(swapfile_name, 'B')
28899499b1cSBram Moolenaar
28999499b1cSBram Moolenaar  " Close and delete the file and recreate the swap file.
29099499b1cSBram Moolenaar  quit
29199499b1cSBram Moolenaar  call delete('Xtest.scr')
29299499b1cSBram Moolenaar  call writefile(swapfile_bytes, swapfile_name)
29399499b1cSBram Moolenaar  " Edit the file again. This triggers recovery.
29499499b1cSBram Moolenaar  try
29599499b1cSBram Moolenaar    split Xtest.scr
29699499b1cSBram Moolenaar  catch
29799499b1cSBram Moolenaar    " E308 should be caught, not E306.
29899499b1cSBram Moolenaar    call assert_exception('E308:')  " Original file may have been changed
29999499b1cSBram Moolenaar  endtry
30099499b1cSBram Moolenaar  " The file should be recovered.
30199499b1cSBram Moolenaar  call assert_equal(['one', 'two', 'three'], getline(1, 3))
30299499b1cSBram Moolenaar  quit!
30399499b1cSBram Moolenaar
30499499b1cSBram Moolenaar  call delete('Xtest.scr')
30599499b1cSBram Moolenaar  call delete(swapfile_name)
30699499b1cSBram Moolenaar  augroup test_swap_recover_ext
30799499b1cSBram Moolenaar    autocmd!
30899499b1cSBram Moolenaar  augroup END
30999499b1cSBram Moolenaar  augroup! test_swap_recover_ext
31099499b1cSBram Moolenaarendfunc
311406cd90fSBram Moolenaar
312406cd90fSBram Moolenaar" Test for closing a split window automatically when a swap file is detected
313406cd90fSBram Moolenaar" and 'Q' is selected in the confirmation prompt.
314406cd90fSBram Moolenaarfunc Test_swap_split_win()
315406cd90fSBram Moolenaar  autocmd! SwapExists
316406cd90fSBram Moolenaar  augroup test_swap_splitwin
317406cd90fSBram Moolenaar    autocmd!
318406cd90fSBram Moolenaar    autocmd SwapExists * let v:swapchoice = 'q'
319406cd90fSBram Moolenaar  augroup END
320406cd90fSBram Moolenaar
321406cd90fSBram Moolenaar  " Create a valid swapfile by editing a file with a special extension.
322406cd90fSBram Moolenaar  split Xtest.scr
323406cd90fSBram Moolenaar  call setline(1, ['one', 'two', 'three'])
324406cd90fSBram Moolenaar  write  " file is written, not modified
325406cd90fSBram Moolenaar  write  " write again to make sure the swapfile is created
326406cd90fSBram Moolenaar  " read the swapfile as a Blob
327406cd90fSBram Moolenaar  let swapfile_name = swapname('%')
328406cd90fSBram Moolenaar  let swapfile_bytes = readfile(swapfile_name, 'B')
329406cd90fSBram Moolenaar
330406cd90fSBram Moolenaar  " Close and delete the file and recreate the swap file.
331406cd90fSBram Moolenaar  quit
332406cd90fSBram Moolenaar  call delete('Xtest.scr')
333406cd90fSBram Moolenaar  call writefile(swapfile_bytes, swapfile_name)
334406cd90fSBram Moolenaar  " Split edit the file again. This should fail to open the window
335406cd90fSBram Moolenaar  try
336406cd90fSBram Moolenaar    split Xtest.scr
337406cd90fSBram Moolenaar  catch
338406cd90fSBram Moolenaar    " E308 should be caught, not E306.
339406cd90fSBram Moolenaar    call assert_exception('E308:')  " Original file may have been changed
340406cd90fSBram Moolenaar  endtry
341406cd90fSBram Moolenaar  call assert_equal(1, winnr('$'))
342406cd90fSBram Moolenaar
343406cd90fSBram Moolenaar  call delete('Xtest.scr')
344406cd90fSBram Moolenaar  call delete(swapfile_name)
345406cd90fSBram Moolenaar
346406cd90fSBram Moolenaar  augroup test_swap_splitwin
347406cd90fSBram Moolenaar      autocmd!
348406cd90fSBram Moolenaar  augroup END
349406cd90fSBram Moolenaar  augroup! test_swap_splitwin
350406cd90fSBram Moolenaarendfunc
351406cd90fSBram Moolenaar
352b654103aSBram Moolenaar" Test for selecting 'q' in the attention prompt
353b654103aSBram Moolenaarfunc Test_swap_prompt_splitwin()
354d36ef573SBram Moolenaar  CheckRunVimInTerminal
355d36ef573SBram Moolenaar
356b654103aSBram Moolenaar  call writefile(['foo bar'], 'Xfile1')
357b654103aSBram Moolenaar  edit Xfile1
358d36ef573SBram Moolenaar  preserve  " should help to make sure the swap file exists
359d36ef573SBram Moolenaar
360b654103aSBram Moolenaar  let buf = RunVimInTerminal('', {'rows': 20})
361b654103aSBram Moolenaar  call term_sendkeys(buf, ":set nomore\n")
362b654103aSBram Moolenaar  call term_sendkeys(buf, ":set noruler\n")
3631d97efceSBram Moolenaar
364b654103aSBram Moolenaar  call term_sendkeys(buf, ":split Xfile1\n")
3656a2c5a7dSBram Moolenaar  call TermWait(buf)
366b654103aSBram Moolenaar  call WaitForAssert({-> assert_match('^\[O\]pen Read-Only, (E)dit anyway, (R)ecover, (Q)uit, (A)bort: $', term_getline(buf, 20))})
367b654103aSBram Moolenaar  call term_sendkeys(buf, "q")
3686a2c5a7dSBram Moolenaar  call TermWait(buf)
369d36ef573SBram Moolenaar  call term_sendkeys(buf, ":\<CR>")
370b654103aSBram Moolenaar  call WaitForAssert({-> assert_match('^:$', term_getline(buf, 20))})
371d36ef573SBram Moolenaar  call term_sendkeys(buf, ":echomsg winnr('$')\<CR>")
3726a2c5a7dSBram Moolenaar  call TermWait(buf)
373b654103aSBram Moolenaar  call WaitForAssert({-> assert_match('^1$', term_getline(buf, 20))})
374b654103aSBram Moolenaar  call StopVimInTerminal(buf)
3751d97efceSBram Moolenaar
3763777d6e3SBram Moolenaar  " This caused Vim to crash when typing "q" at the swap file prompt.
3773777d6e3SBram Moolenaar  let buf = RunVimInTerminal('-c "au bufadd * let foo_w = wincol()"', {'rows': 18})
3783777d6e3SBram Moolenaar  call term_sendkeys(buf, ":e Xfile1\<CR>")
3793777d6e3SBram Moolenaar  call WaitForAssert({-> assert_match('More', term_getline(buf, 18))})
3803777d6e3SBram Moolenaar  call term_sendkeys(buf, " ")
3813777d6e3SBram Moolenaar  call WaitForAssert({-> assert_match('^\[O\]pen Read-Only, (E)dit anyway, (R)ecover, (Q)uit, (A)bort:', term_getline(buf, 18))})
3821d97efceSBram Moolenaar  call term_sendkeys(buf, "q")
3833777d6e3SBram Moolenaar  call TermWait(buf)
3843777d6e3SBram Moolenaar  " check that Vim is still running
3853777d6e3SBram Moolenaar  call term_sendkeys(buf, ":echo 'hello'\<CR>")
3863777d6e3SBram Moolenaar  call WaitForAssert({-> assert_match('^hello', term_getline(buf, 18))})
3873777d6e3SBram Moolenaar  call term_sendkeys(buf, ":%bwipe!\<CR>")
3883777d6e3SBram Moolenaar  call StopVimInTerminal(buf)
3891d97efceSBram Moolenaar
390b654103aSBram Moolenaar  %bwipe!
391b654103aSBram Moolenaar  call delete('Xfile1')
392b654103aSBram Moolenaarendfunc
393b654103aSBram Moolenaar
3945966ea10SBram Moolenaarfunc Test_swap_symlink()
3956d91bcb4SBram Moolenaar  CheckUnix
3965966ea10SBram Moolenaar
3975966ea10SBram Moolenaar  call writefile(['text'], 'Xtestfile')
3985966ea10SBram Moolenaar  silent !ln -s -f Xtestfile Xtestlink
3995966ea10SBram Moolenaar
4005966ea10SBram Moolenaar  set dir=.
4015966ea10SBram Moolenaar
4025966ea10SBram Moolenaar  " Test that swap file uses the name of the file when editing through a
4035966ea10SBram Moolenaar  " symbolic link (so that editing the file twice is detected)
4045966ea10SBram Moolenaar  edit Xtestlink
4055966ea10SBram Moolenaar  call assert_match('Xtestfile\.swp$', s:swapname())
4065966ea10SBram Moolenaar  bwipe!
4075966ea10SBram Moolenaar
4085966ea10SBram Moolenaar  call mkdir('Xswapdir')
4095966ea10SBram Moolenaar  exe 'set dir=' . getcwd() . '/Xswapdir//'
4105966ea10SBram Moolenaar
4115966ea10SBram Moolenaar  " Check that this also works when 'directory' ends with '//'
4125966ea10SBram Moolenaar  edit Xtestlink
413*8b0e62c9SBram Moolenaar  call assert_match('Xswapdir[/\\]%.*testdir%Xtestfile\.swp$', s:swapname())
4145966ea10SBram Moolenaar  bwipe!
4155966ea10SBram Moolenaar
4165966ea10SBram Moolenaar  set dir&
4175966ea10SBram Moolenaar  call delete('Xtestfile')
4185966ea10SBram Moolenaar  call delete('Xtestlink')
4195966ea10SBram Moolenaar  call delete('Xswapdir', 'rf')
4205966ea10SBram Moolenaarendfunc
4215966ea10SBram Moolenaar
4225ee0981fSBram Moolenaarfunc s:get_unused_pid(base)
4235ee0981fSBram Moolenaar  if has('job')
4245ee0981fSBram Moolenaar    " Execute 'echo' as a temporary job, and return its pid as an unused pid.
4255ee0981fSBram Moolenaar    if has('win32')
4265ee0981fSBram Moolenaar      let cmd = 'cmd /c echo'
4275ee0981fSBram Moolenaar    else
4285ee0981fSBram Moolenaar      let cmd = 'echo'
4295ee0981fSBram Moolenaar    endif
4305ee0981fSBram Moolenaar    let j = job_start(cmd)
4315ee0981fSBram Moolenaar    while job_status(j) ==# 'run'
4325ee0981fSBram Moolenaar      sleep 10m
4335ee0981fSBram Moolenaar    endwhile
4345ee0981fSBram Moolenaar    if job_status(j) ==# 'dead'
4355ee0981fSBram Moolenaar      return job_info(j).process
4365ee0981fSBram Moolenaar    endif
4375ee0981fSBram Moolenaar  endif
4385ee0981fSBram Moolenaar  " Must add four for MS-Windows to see it as a different one.
4395ee0981fSBram Moolenaar  return a:base + 4
4405ee0981fSBram Moolenaarendfunc
4415ee0981fSBram Moolenaar
4425ee0981fSBram Moolenaarfunc s:blob_to_pid(b)
4435ee0981fSBram Moolenaar  return a:b[3] * 16777216 + a:b[2] * 65536 + a:b[1] * 256 + a:b[0]
4445ee0981fSBram Moolenaarendfunc
4455ee0981fSBram Moolenaar
4465ee0981fSBram Moolenaarfunc s:pid_to_blob(i)
4475ee0981fSBram Moolenaar  let b = 0z
4485ee0981fSBram Moolenaar  let b[0] = and(a:i, 0xff)
4495ee0981fSBram Moolenaar  let b[1] = and(a:i / 256, 0xff)
4505ee0981fSBram Moolenaar  let b[2] = and(a:i / 65536, 0xff)
4515ee0981fSBram Moolenaar  let b[3] = and(a:i / 16777216, 0xff)
4525ee0981fSBram Moolenaar  return b
4535ee0981fSBram Moolenaarendfunc
4545ee0981fSBram Moolenaar
455f883508eSBram Moolenaarfunc Test_swap_auto_delete()
456f883508eSBram Moolenaar  " Create a valid swapfile by editing a file with a special extension.
457f883508eSBram Moolenaar  split Xtest.scr
458f883508eSBram Moolenaar  call setline(1, ['one', 'two', 'three'])
459f883508eSBram Moolenaar  write  " file is written, not modified
460f883508eSBram Moolenaar  write  " write again to make sure the swapfile is created
461f883508eSBram Moolenaar  " read the swapfile as a Blob
462f883508eSBram Moolenaar  let swapfile_name = swapname('%')
463f883508eSBram Moolenaar  let swapfile_bytes = readfile(swapfile_name, 'B')
464f883508eSBram Moolenaar
465f883508eSBram Moolenaar  " Forget about the file, recreate the swap file, then edit it again.  The
466f883508eSBram Moolenaar  " swap file should be automatically deleted.
467f883508eSBram Moolenaar  bwipe!
4685ee0981fSBram Moolenaar  " Change the process ID to avoid the "still running" warning.
4695ee0981fSBram Moolenaar  let swapfile_bytes[24:27] = s:pid_to_blob(s:get_unused_pid(
4705ee0981fSBram Moolenaar        \ s:blob_to_pid(swapfile_bytes[24:27])))
471f883508eSBram Moolenaar  call writefile(swapfile_bytes, swapfile_name)
472f883508eSBram Moolenaar  edit Xtest.scr
473f883508eSBram Moolenaar  " will end up using the same swap file after deleting the existing one
474f883508eSBram Moolenaar  call assert_equal(swapfile_name, swapname('%'))
475f883508eSBram Moolenaar  bwipe!
476f883508eSBram Moolenaar
477f883508eSBram Moolenaar  " create the swap file again, but change the host name so that it won't be
478f883508eSBram Moolenaar  " deleted
479f883508eSBram Moolenaar  autocmd! SwapExists
480f883508eSBram Moolenaar  augroup test_swap_recover_ext
481f883508eSBram Moolenaar    autocmd!
482f883508eSBram Moolenaar    autocmd SwapExists * let v:swapchoice = 'e'
483f883508eSBram Moolenaar  augroup END
484f883508eSBram Moolenaar
485f883508eSBram Moolenaar  " change the host name
486c6ca9f3aSBram Moolenaar  let swapfile_bytes[28 + 40] = swapfile_bytes[28 + 40] + 2
487f883508eSBram Moolenaar  call writefile(swapfile_bytes, swapfile_name)
488f883508eSBram Moolenaar  edit Xtest.scr
489f883508eSBram Moolenaar  call assert_equal(1, filereadable(swapfile_name))
490f883508eSBram Moolenaar  " will use another same swap file name
491f883508eSBram Moolenaar  call assert_notequal(swapfile_name, swapname('%'))
492f883508eSBram Moolenaar  bwipe!
493f883508eSBram Moolenaar
494f883508eSBram Moolenaar  call delete('Xtest.scr')
495f883508eSBram Moolenaar  call delete(swapfile_name)
496f883508eSBram Moolenaar  augroup test_swap_recover_ext
497f883508eSBram Moolenaar    autocmd!
498f883508eSBram Moolenaar  augroup END
499f883508eSBram Moolenaar  augroup! test_swap_recover_ext
500f883508eSBram Moolenaarendfunc
501f883508eSBram Moolenaar
50259b26236SYegappan Lakshmanan" Test for renaming a buffer when the swap file is deleted out-of-band
50359b26236SYegappan Lakshmananfunc Test_missing_swap_file()
50459b26236SYegappan Lakshmanan  CheckUnix
505f33cae60SBram Moolenaar  new Xfile2
50699285550SYegappan Lakshmanan  call delete(swapname(''))
507f33cae60SBram Moolenaar  call assert_fails('file Xfile3', 'E301:')
508f33cae60SBram Moolenaar  call assert_equal('Xfile3', bufname())
50959b26236SYegappan Lakshmanan  call assert_true(bufexists('Xfile2'))
510f33cae60SBram Moolenaar  call assert_true(bufexists('Xfile3'))
51159b26236SYegappan Lakshmanan  %bw!
51259b26236SYegappan Lakshmananendfunc
51359b26236SYegappan Lakshmanan
51459b26236SYegappan Lakshmanan" Test for :preserve command
51559b26236SYegappan Lakshmananfunc Test_preserve()
516f33cae60SBram Moolenaar  new Xfile4
51759b26236SYegappan Lakshmanan  setlocal noswapfile
51859b26236SYegappan Lakshmanan  call assert_fails('preserve', 'E313:')
51959b26236SYegappan Lakshmanan  bw!
52059b26236SYegappan Lakshmananendfunc
52159b26236SYegappan Lakshmanan
52259b26236SYegappan Lakshmanan" Test for the v:swapchoice variable
52359b26236SYegappan Lakshmananfunc Test_swapchoice()
524f33cae60SBram Moolenaar  call writefile(['aaa', 'bbb'], 'Xfile5')
525f33cae60SBram Moolenaar  edit Xfile5
52659b26236SYegappan Lakshmanan  preserve
52759b26236SYegappan Lakshmanan  let swapfname = swapname('')
52859b26236SYegappan Lakshmanan  let b = readblob(swapfname)
52959b26236SYegappan Lakshmanan  bw!
53059b26236SYegappan Lakshmanan  call writefile(b, swapfname)
53159b26236SYegappan Lakshmanan
53259b26236SYegappan Lakshmanan  autocmd! SwapExists
53359b26236SYegappan Lakshmanan
53459b26236SYegappan Lakshmanan  " Test for v:swapchoice = 'o' (readonly)
53559b26236SYegappan Lakshmanan  augroup test_swapchoice
53659b26236SYegappan Lakshmanan    autocmd!
53759b26236SYegappan Lakshmanan    autocmd SwapExists * let v:swapchoice = 'o'
53859b26236SYegappan Lakshmanan  augroup END
539f33cae60SBram Moolenaar  edit Xfile5
54059b26236SYegappan Lakshmanan  call assert_true(&readonly)
54159b26236SYegappan Lakshmanan  call assert_equal(['aaa', 'bbb'], getline(1, '$'))
54259b26236SYegappan Lakshmanan  %bw!
54359b26236SYegappan Lakshmanan  call assert_true(filereadable(swapfname))
54459b26236SYegappan Lakshmanan
54559b26236SYegappan Lakshmanan  " Test for v:swapchoice = 'a' (abort)
54659b26236SYegappan Lakshmanan  augroup test_swapchoice
54759b26236SYegappan Lakshmanan    autocmd!
54859b26236SYegappan Lakshmanan    autocmd SwapExists * let v:swapchoice = 'a'
54959b26236SYegappan Lakshmanan  augroup END
55059b26236SYegappan Lakshmanan  try
551f33cae60SBram Moolenaar    edit Xfile5
55259b26236SYegappan Lakshmanan  catch /^Vim:Interrupt$/
55359b26236SYegappan Lakshmanan  endtry
55459b26236SYegappan Lakshmanan  call assert_equal('', @%)
555f33cae60SBram Moolenaar  call assert_true(bufexists('Xfile5'))
55659b26236SYegappan Lakshmanan  %bw!
55759b26236SYegappan Lakshmanan  call assert_true(filereadable(swapfname))
55859b26236SYegappan Lakshmanan
55959b26236SYegappan Lakshmanan  " Test for v:swapchoice = 'd' (delete)
56059b26236SYegappan Lakshmanan  augroup test_swapchoice
56159b26236SYegappan Lakshmanan    autocmd!
56259b26236SYegappan Lakshmanan    autocmd SwapExists * let v:swapchoice = 'd'
56359b26236SYegappan Lakshmanan  augroup END
564f33cae60SBram Moolenaar  edit Xfile5
565f33cae60SBram Moolenaar  call assert_equal('Xfile5', @%)
56659b26236SYegappan Lakshmanan  %bw!
56759b26236SYegappan Lakshmanan  call assert_false(filereadable(swapfname))
56859b26236SYegappan Lakshmanan
569f33cae60SBram Moolenaar  call delete('Xfile5')
57059b26236SYegappan Lakshmanan  call delete(swapfname)
57159b26236SYegappan Lakshmanan  augroup test_swapchoice
57259b26236SYegappan Lakshmanan    autocmd!
57359b26236SYegappan Lakshmanan  augroup END
57459b26236SYegappan Lakshmanan  augroup! test_swapchoice
57559b26236SYegappan Lakshmananendfunc
57659b26236SYegappan Lakshmanan
577fe3418abSDominique Pellefunc Test_no_swap_file()
578fe3418abSDominique Pelle  call assert_equal("\nNo swap file", execute('swapname'))
579fe3418abSDominique Pelleendfunc
580fe3418abSDominique Pelle
581406cd90fSBram Moolenaar" vim: shiftwidth=2 sts=2 expandtab
582