neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

test_mksession.vim (30980B)


      1 " Test for :mksession, :mkview and :loadview in latin1 encoding
      2 
      3 scriptencoding latin1
      4 
      5 source check.vim
      6 CheckFeature mksession
      7 
      8 source shared.vim
      9 source term_util.vim
     10 
     11 " Test for storing global and local argument list in a session file
     12 " This one must be done first.
     13 func Test__mksession_arglocal()
     14  enew | only
     15  n a b c
     16  new
     17  arglocal
     18  mksession! Xtest_mks.out
     19 
     20  %bwipe!
     21  %argdelete
     22  argglobal
     23  source Xtest_mks.out
     24  call assert_equal(2, winnr('$'))
     25  call assert_equal(2, arglistid(1))
     26  call assert_equal(0, arglistid(2))
     27 
     28  %bwipe!
     29  %argdelete
     30  argglobal
     31  call delete('Xtest_mks.out')
     32 endfunc
     33 
     34 func Test_mksession_arglocal_localdir()
     35  call mkdir('Xa', 'R')
     36  call writefile(['This is Xb'], 'Xa/Xb.txt', 'D')
     37  let olddir = getcwd()
     38  let oldargs = argv()
     39 
     40  for tabpage in [v:false, v:true]
     41    let msg = tabpage ? 'tabpage-local' : 'window-local'
     42 
     43    exe tabpage ? 'tabnew' : 'botright new'
     44    exe tabpage ? 'tcd Xa' : 'lcd Xa'
     45    let localdir = getcwd()
     46    arglocal
     47    $argadd Xb.txt
     48    let localargs = argv()
     49    exe tabpage ? 'tabprev' : 'wincmd p'
     50    call assert_equal(olddir, getcwd(), msg)
     51    call assert_equal(oldargs, argv(), msg)
     52    mksession! Xtest_mks_localdir.out
     53    exe tabpage ? '+tabclose' : '$close'
     54    bwipe! Xa/Xb.txt
     55 
     56    source Xtest_mks_localdir.out
     57    exe tabpage ? 'tabnext' : 'wincmd b'
     58    call assert_equal(localdir, getcwd(), msg)
     59    call assert_equal(localargs, argv(), msg)
     60    $argument
     61    call assert_equal('This is Xb', getline(1), msg)
     62 
     63    bwipe!
     64    call assert_equal(olddir, getcwd(), msg)
     65    call assert_equal(oldargs, argv(), msg)
     66    call delete('Xtest_mks_localdir.out')
     67  endfor
     68 endfunc
     69 
     70 func Test_mksession()
     71  tabnew
     72  let wrap_save = &wrap
     73  set sessionoptions=buffers splitbelow fileencoding=latin1
     74  call setline(1, [
     75    \   'start:',
     76    \   'no multibyte chAracter',
     77    \   '	one leaDing tab',
     78    \   '    four leadinG spaces',
     79    \   'two		consecutive tabs',
     80    \   'two	tabs	in one line',
     81    \   'one � multibyteCharacter',
     82    \   'a� �  two multiByte characters',
     83    \   'A���  three mulTibyte characters',
     84    \   'short line',
     85    \ ])
     86  let tmpfile = 'Xtemp'
     87  exec 'w! ' . tmpfile
     88  /^start:
     89  set wrap
     90  vsplit
     91  norm! j16|
     92  split
     93  norm! j16|
     94  split
     95  norm! j16|
     96  split
     97  norm! j8|
     98  split
     99  norm! j8|
    100  split
    101  norm! j16|
    102  split
    103  norm! j16|
    104  split
    105  norm! j16|
    106  split
    107  norm! j$
    108  wincmd l
    109 
    110  set nowrap
    111  /^start:
    112  norm! j16|3zl
    113  split
    114  norm! j016|3zl
    115  split
    116  norm! j016|3zl
    117  split
    118  norm! j08|3zl
    119  split
    120  norm! j08|3zl
    121  split
    122  norm! j016|3zl
    123  split
    124  norm! j016|3zl
    125  split
    126  norm! j016|3zl
    127  split
    128  call wincol()
    129  mksession! Xtest_mks.out
    130  let li = filter(readfile('Xtest_mks.out'), 'v:val =~# "\\(^ *normal! [0$]\\|^ *exe ''normal!\\)"')
    131  let expected = [
    132    \   'normal! 016|',
    133    \   'normal! 016|',
    134    \   'normal! 016|',
    135    \   'normal! 08|',
    136    \   'normal! 08|',
    137    \   'normal! 016|',
    138    \   'normal! 016|',
    139    \   'normal! 016|',
    140    \   'normal! $',
    141    \   "  exe 'normal! ' . s:c . '|zs' . 16 . '|'",
    142    \   "  normal! 016|",
    143    \   "  exe 'normal! ' . s:c . '|zs' . 16 . '|'",
    144    \   "  normal! 016|",
    145    \   "  exe 'normal! ' . s:c . '|zs' . 16 . '|'",
    146    \   "  normal! 016|",
    147    \   "  exe 'normal! ' . s:c . '|zs' . 8 . '|'",
    148    \   "  normal! 08|",
    149    \   "  exe 'normal! ' . s:c . '|zs' . 8 . '|'",
    150    \   "  normal! 08|",
    151    \   "  exe 'normal! ' . s:c . '|zs' . 16 . '|'",
    152    \   "  normal! 016|",
    153    \   "  exe 'normal! ' . s:c . '|zs' . 16 . '|'",
    154    \   "  normal! 016|",
    155    \   "  exe 'normal! ' . s:c . '|zs' . 16 . '|'",
    156    \   "  normal! 016|",
    157    \   "  exe 'normal! ' . s:c . '|zs' . 16 . '|'",
    158    \   "  normal! 016|"
    159    \ ]
    160  call assert_equal(expected, li)
    161  tabclose!
    162 
    163  call delete('Xtest_mks.out')
    164  call delete(tmpfile)
    165  let &wrap = wrap_save
    166  set sessionoptions&
    167 endfunc
    168 
    169 func Test_mksession_winheight()
    170  new
    171  set winheight=10
    172  set winminheight=2
    173  mksession! Xtest_mks.out
    174  source Xtest_mks.out
    175 
    176  call delete('Xtest_mks.out')
    177 endfunc
    178 
    179 func Test_mksession_large_winheight()
    180  set winheight=999
    181  mksession! Xtest_mks_winheight.out
    182  set winheight&
    183  source Xtest_mks_winheight.out
    184  call delete('Xtest_mks_winheight.out')
    185 endfunc
    186 
    187 func Test_mksession_zero_winheight()
    188  set winminheight=0
    189  edit SomeFile
    190  split
    191  wincmd _
    192  mksession! Xtest_mks_zero
    193  set winminheight&
    194  let text = readfile('Xtest_mks_zero')->join()
    195  call delete('Xtest_mks_zero')
    196  close
    197  " check there is no divide by zero
    198  call assert_notmatch('/ 0[^0-9]', text)
    199 endfunc
    200 
    201 func Test_mksession_rtp()
    202  if has('win32')
    203    " TODO: fix problem with backslashes
    204    return
    205  endif
    206  new
    207  let _rtp=&rtp
    208  " Make a real long (invalid) runtimepath value,
    209  " that should exceed PATH_MAX (hopefully)
    210  let newrtp=&rtp.',~'.repeat('/foobar', 1000)
    211  let newrtp.=",".expand("$HOME")."/.vim"
    212  let &rtp=newrtp
    213 
    214  " determine expected value
    215  let expected=split(&rtp, ',')
    216  let expected = map(expected, '"set runtimepath+=".v:val')
    217  let expected = ['set runtimepath='] + expected
    218  let expected = map(expected, {v,w -> substitute(w, $HOME, "~", "g")})
    219 
    220  mksession! Xtest_mks.out
    221  let &rtp=_rtp
    222  let li = filter(readfile('Xtest_mks.out'), 'v:val =~# "runtimepath"')
    223  call assert_equal(expected, li)
    224 
    225  call delete('Xtest_mks.out')
    226 endfunc
    227 
    228 func Test_mksession_arglist()
    229  %argdel
    230  next file1 file2 file3 file4
    231  new
    232  next | next
    233  mksession! Xtest_mks.out
    234  source Xtest_mks.out
    235  call assert_equal(['file1', 'file2', 'file3', 'file4'], argv())
    236  call assert_equal(2, argidx())
    237  wincmd w
    238  call assert_equal(0, argidx())
    239 
    240  call delete('Xtest_mks.out')
    241  enew | only
    242  argdel *
    243 endfunc
    244 
    245 func Test_mksession_one_buffer_two_windows()
    246  edit Xtest1
    247  new Xtest2
    248  split
    249  mksession! Xtest_mks.out
    250  let lines = readfile('Xtest_mks.out')
    251  let count1 = 0
    252  let count2 = 0
    253  let count2buf = 0
    254  let bufexists = 0
    255  for line in lines
    256    if line =~ 'edit \f*Xtest1$'
    257      let count1 += 1
    258    endif
    259    if line =~ 'edit \f\{-}Xtest2'
    260      let count2 += 1
    261    endif
    262    if line =~ 'buffer \f\{-}Xtest2'
    263      let count2buf += 1
    264    endif
    265    if line =~ 'bufexists(fnamemodify(.*, ":p")'
    266      let bufexists += 1
    267    endif
    268  endfor
    269  call assert_equal(1, count1, 'Xtest1 count')
    270  call assert_equal(2, count2, 'Xtest2 count')
    271  call assert_equal(2, count2buf, 'Xtest2 buffer count')
    272  call assert_equal(2, bufexists)
    273 
    274  close
    275  bwipe!
    276  call delete('Xtest_mks.out')
    277 endfunc
    278 
    279 func Test_mksession_lcd_multiple_tabs()
    280  tabnew
    281  tabnew
    282  lcd .
    283  tabfirst
    284  lcd .
    285  mksession! Xtest_mks.out
    286  tabonly
    287  source Xtest_mks.out
    288  call assert_true(haslocaldir(), 'Tab 1 localdir')
    289  tabnext 2
    290  call assert_true(!haslocaldir(), 'Tab 2 localdir')
    291  tabnext 3
    292  call assert_true(haslocaldir(), 'Tab 3 localdir')
    293  call delete('Xtest_mks.out')
    294 endfunc
    295 
    296 " Test for tabpage-local directory
    297 func Test_mksession_tcd_multiple_tabs()
    298  let save_cwd = getcwd()
    299  call mkdir('Xtopdir')
    300  cd Xtopdir
    301  call mkdir('Xtabdir1')
    302  call mkdir('Xtabdir2')
    303  call mkdir('Xtabdir3')
    304  call mkdir('Xwindir1')
    305  call mkdir('Xwindir2')
    306  call mkdir('Xwindir3')
    307  tcd Xtabdir1
    308  botright new
    309  wincmd t
    310  lcd ../Xwindir1
    311  tabnew
    312  tcd ../Xtabdir2
    313  botright new
    314  lcd ../Xwindir2
    315  tabnew
    316  tcd ../Xtabdir3
    317  botright new
    318  lcd ../Xwindir3
    319  tabfirst
    320  1wincmd w
    321  mksession! Xtest_mks.out
    322  only | tabonly
    323  source Xtest_mks.out
    324  call assert_equal('Xtabdir1', fnamemodify(getcwd(-1, 1), ':t'))
    325  call assert_equal('Xwindir1', fnamemodify(getcwd(1, 1), ':t'))
    326  call assert_equal('Xtabdir1', fnamemodify(getcwd(2, 1), ':t'))
    327  call assert_equal('Xtabdir2', fnamemodify(getcwd(-1, 2), ':t'))
    328  call assert_equal('Xtabdir2', fnamemodify(getcwd(1, 2), ':t'))
    329  call assert_equal('Xwindir2', fnamemodify(getcwd(2, 2), ':t'))
    330  call assert_equal('Xtabdir3', fnamemodify(getcwd(-1, 3), ':t'))
    331  call assert_equal('Xtabdir3', fnamemodify(getcwd(1, 3), ':t'))
    332  call assert_equal('Xwindir3', fnamemodify(getcwd(2, 3), ':t'))
    333  %bwipe
    334  call chdir(save_cwd)
    335  call delete("Xtopdir", "rf")
    336 endfunc
    337 
    338 func Test_mksession_blank_tabs()
    339  tabnew
    340  tabnew
    341  tabnew
    342  tabnext 3
    343  mksession! Xtest_mks.out
    344  tabnew
    345  tabnew
    346  tabnext 2
    347  source Xtest_mks.out
    348  call assert_equal(4, tabpagenr('$'), 'session restore should restore number of tabs')
    349  call assert_equal(3, tabpagenr(), 'session restore should restore the active tab')
    350  call delete('Xtest_mks.out')
    351 endfunc
    352 
    353 func Test_mksession_buffer_count()
    354  set hidden
    355 
    356  " Edit exactly three files in the current session.
    357  %bwipe!
    358  e Xfoo | tabe Xbar | tabe Xbaz
    359  tabdo write
    360  mksession! Xtest_mks.out
    361 
    362  " Verify that loading the session does not create additional buffers.
    363  %bwipe!
    364  source Xtest_mks.out
    365  call assert_equal(3, len(getbufinfo()))
    366 
    367  " Clean up.
    368  call delete('Xfoo')
    369  call delete('Xbar')
    370  call delete('Xbaz')
    371  call delete('Xtest_mks.out')
    372  %bwipe!
    373  set hidden&
    374 endfunc
    375 
    376 func Test_mksession_buffer_order()
    377  %bwipe!
    378  e Xfoo | e Xbar | e Xbaz | e Xqux
    379  bufdo write
    380  mksession! Xtest_mks.out
    381 
    382  " Verify that loading the session preserves order of buffers
    383  %bwipe!
    384  source Xtest_mks.out
    385 
    386  let s:buf_info = getbufinfo()
    387  call assert_true(s:buf_info[0]['name'] =~# 'Xfoo$')
    388  call assert_true(s:buf_info[1]['name'] =~# 'Xbar$')
    389  call assert_true(s:buf_info[2]['name'] =~# 'Xbaz$')
    390  call assert_true(s:buf_info[3]['name'] =~# 'Xqux$')
    391 
    392  " Clean up.
    393  call delete('Xfoo')
    394  call delete('Xbar')
    395  call delete('Xbaz')
    396  call delete('Xqux')
    397  call delete('Xtest_mks.out')
    398  %bwipe!
    399 endfunc
    400 
    401 if has('extra_search')
    402 
    403 func Test_mksession_hlsearch()
    404  set hlsearch
    405  mksession! Xtest_mks.out
    406  nohlsearch
    407  source Xtest_mks.out
    408  call assert_equal(1, v:hlsearch, 'session should restore search highlighting state')
    409  nohlsearch
    410  mksession! Xtest_mks.out
    411  source Xtest_mks.out
    412  call assert_equal(0, v:hlsearch, 'session should restore search highlighting state')
    413  call delete('Xtest_mks.out')
    414 endfunc
    415 
    416 endif
    417 
    418 
    419 func Test_mksession_blank_windows()
    420  split
    421  split
    422  split
    423  3 wincmd w
    424  mksession! Xtest_mks.out
    425  split
    426  split
    427  2 wincmd w
    428  source Xtest_mks.out
    429  call assert_equal(4, winnr('$'), 'session restore should restore number of windows')
    430  call assert_equal(3, winnr(), 'session restore should restore the active window')
    431  call delete('Xtest_mks.out')
    432 endfunc
    433 
    434 if has('terminal')
    435 
    436 func Test_mksession_terminal_shell()
    437  CheckFeature quickfix
    438 
    439  terminal
    440  mksession! Xtest_mks.out
    441  let lines = readfile('Xtest_mks.out')
    442  let term_cmd = ''
    443  for line in lines
    444    if line =~ '^terminal'
    445      let term_cmd = line
    446    elseif line =~ 'badd.*' . &shell
    447      call assert_report('unexpected shell line: ' . line)
    448    endif
    449  endfor
    450  call assert_match('terminal ++curwin ++cols=\d\+ ++rows=\d\+\s*.*$', term_cmd)
    451 
    452  call StopShellInTerminal(bufnr('%'))
    453  call delete('Xtest_mks.out')
    454 endfunc
    455 
    456 func Test_mksession_terminal_no_restore_cmdarg()
    457  terminal ++norestore
    458  mksession! Xtest_mks.out
    459  let lines = readfile('Xtest_mks.out')
    460  let term_cmd = ''
    461  for line in lines
    462    if line =~ '^terminal'
    463      call assert_report('session must not restore terminal')
    464    endif
    465  endfor
    466 
    467  call StopShellInTerminal(bufnr('%'))
    468  call delete('Xtest_mks.out')
    469 endfunc
    470 
    471 func Test_mksession_terminal_no_restore_funcarg()
    472  call term_start(&shell, {'norestore': 1})
    473  mksession! Xtest_mks.out
    474  let lines = readfile('Xtest_mks.out')
    475  let term_cmd = ''
    476  for line in lines
    477    if line =~ '^terminal'
    478      call assert_report('session must not restore terminal')
    479    endif
    480  endfor
    481 
    482  call StopShellInTerminal(bufnr('%'))
    483  call delete('Xtest_mks.out')
    484 endfunc
    485 
    486 func Test_mksession_terminal_no_restore_func()
    487  terminal
    488  call term_setrestore(bufnr('%'), 'NONE')
    489  mksession! Xtest_mks.out
    490  let lines = readfile('Xtest_mks.out')
    491  let term_cmd = ''
    492  for line in lines
    493    if line =~ '^terminal'
    494      call assert_report('session must not restore terminal')
    495    endif
    496  endfor
    497 
    498  call StopShellInTerminal(bufnr('%'))
    499  call delete('Xtest_mks.out')
    500 endfunc
    501 
    502 func Test_mksession_terminal_no_ssop()
    503  terminal
    504  set sessionoptions-=terminal
    505  mksession! Xtest_mks.out
    506  let lines = readfile('Xtest_mks.out')
    507  let term_cmd = ''
    508  for line in lines
    509    if line =~ '^terminal'
    510      call assert_report('session must not restore terminal')
    511    endif
    512  endfor
    513 
    514  call StopShellInTerminal(bufnr('%'))
    515  call delete('Xtest_mks.out')
    516  set sessionoptions&
    517 endfunc
    518 
    519 func Test_mksession_terminal_restore_other()
    520  CheckFeature quickfix
    521 
    522  terminal
    523  eval bufnr('%')->term_setrestore('other')
    524  mksession! Xtest_mks.out
    525  let lines = readfile('Xtest_mks.out')
    526  let term_cmd = ''
    527  for line in lines
    528    if line =~ '^terminal'
    529      let term_cmd = line
    530    endif
    531  endfor
    532  call assert_match('terminal ++curwin ++cols=\d\+ ++rows=\d\+.*other', term_cmd)
    533 
    534  call StopShellInTerminal(bufnr('%'))
    535  call delete('Xtest_mks.out')
    536 endfunc
    537 
    538 endif " has('terminal')
    539 
    540 func Test_mkview_open_folds()
    541  enew!
    542 
    543  call append(0, ['a', 'b', 'c'])
    544  1,3fold
    545  write! Xtestfile
    546 
    547  call assert_notequal(-1, foldclosed(1))
    548  call assert_notequal(-1, foldclosed(2))
    549  call assert_notequal(-1, foldclosed(3))
    550 
    551  " Save the view with folds closed
    552  mkview! Xtestview
    553 
    554  " zR affects 'foldlevel', make sure the option is applied after the folds
    555  " have been recreated.
    556  " Open folds to ensure they get closed when restoring the view
    557  normal zR
    558 
    559  call assert_equal(-1, foldclosed(1))
    560  call assert_equal(-1, foldclosed(2))
    561  call assert_equal(-1, foldclosed(3))
    562 
    563  source Xtestview
    564 
    565  call assert_notequal(-1, foldclosed(1))
    566  call assert_notequal(-1, foldclosed(2))
    567  call assert_notequal(-1, foldclosed(3))
    568 
    569  call delete('Xtestview')
    570  call delete('Xtestfile')
    571  %bwipe
    572 endfunc
    573 
    574 func Test_mkview_no_balt()
    575  edit Xtestfile1
    576  edit Xtestfile2
    577 
    578  mkview! Xtestview
    579  bdelete Xtestfile1
    580 
    581  source Xtestview
    582  call assert_equal(0, buflisted('Xtestfile1'))
    583 
    584  call delete('Xtestview')
    585  %bwipe
    586 endfunc
    587 
    588 func Test_mksession_no_balt()
    589  edit Xtestfile1
    590  edit Xtestfile2
    591 
    592  bdelete Xtestfile1
    593  mksession! Xtestview
    594 
    595  source Xtestview
    596  call assert_equal(0, buflisted('Xtestfile1'))
    597 
    598  call delete('Xtestview')
    599  %bwipe
    600 endfunc
    601 
    602 " Test :mkview with a file argument.
    603 func Test_mkview_file()
    604  " Create a view with line number and a fold.
    605  help :mkview
    606  set number
    607  norm! V}zf0
    608  let pos = getpos('.')
    609  let linefoldclosed1 = foldclosed('.')
    610  mkview! Xview
    611  set nonumber
    612  norm! zrj
    613  " We can close the help window, as mkview with a file name should
    614  " generate a command to edit the file.
    615  helpclose
    616 
    617  source Xview
    618  call assert_equal(1, &number)
    619  call assert_match('\*:mkview\*$', getline('.'))
    620  call assert_equal(pos, getpos('.'))
    621  call assert_equal(linefoldclosed1, foldclosed('.'))
    622 
    623  " Creating a view again with the same file name should fail (file
    624  " already exists). But with a !, the previous view should be
    625  " overwritten without error.
    626  help :loadview
    627  call assert_fails('mkview Xview', 'E189:')
    628  call assert_match('\*:loadview\*$', getline('.'))
    629  mkview! Xview
    630  call assert_match('\*:loadview\*$', getline('.'))
    631 
    632  call delete('Xview')
    633  bwipe
    634 endfunc
    635 
    636 " Test :mkview and :loadview with a custom 'viewdir'.
    637 func Test_mkview_loadview_with_viewdir()
    638  set viewdir=Xviewdir
    639 
    640  help :mkview
    641  set number
    642  norm! V}zf
    643  let pos = getpos('.')
    644  let linefoldclosed1 = foldclosed('.')
    645  mkview 1
    646  set nonumber
    647  norm! zrj
    648 
    649  loadview 1
    650 
    651  " The directory Xviewdir/ should have been created and the view
    652  " should be stored in that directory.
    653  call assert_equal('Xviewdir/' .
    654        \           substitute(
    655        \             substitute(
    656        \               expand('%:p'), '/', '=+', 'g'), ':', '=-', 'g') . '=1.vim',
    657        \           glob('Xviewdir/*'))
    658  call assert_equal(1, &number)
    659  call assert_match('\*:mkview\*$', getline('.'))
    660  call assert_equal(pos, getpos('.'))
    661  call assert_equal(linefoldclosed1, foldclosed('.'))
    662 
    663  call delete('Xviewdir', 'rf')
    664  set viewdir&
    665  helpclose
    666 endfunc
    667 
    668 func Test_mkview_no_file_name()
    669  new
    670  " :mkview or :mkview {nr} should fail in an unnamed buffer.
    671  call assert_fails('mkview', 'E32:')
    672  call assert_fails('mkview 1', 'E32:')
    673 
    674  " :mkview {file} should succeed in an unnamed buffer.
    675  mkview Xview
    676  help
    677  source Xview
    678  call assert_equal('', bufname('%'))
    679 
    680  call delete('Xview')
    681  %bwipe
    682 endfunc
    683 
    684 func Test_mkview_loadview_jumplist()
    685  set viewdir=Xviewdir
    686  au BufWinLeave * silent mkview
    687  " au BufWinEnter * silent loadview
    688 
    689  edit Xfile1
    690  call setline(1, ['a', 'bbbbbbb', 'c'])
    691  normal j3l
    692  call assert_equal([2, 4], getcurpos()[1:2])
    693  write
    694 
    695  edit Xfile2
    696  call setline(1, ['d', 'eeeeeee', 'f'])
    697  normal j5l
    698  call assert_equal([2, 6], getcurpos()[1:2])
    699  write
    700 
    701  edit Xfile3
    702  call setline(1, ['g', 'h', 'iiiii'])
    703  normal jj3l
    704  call assert_equal([3, 4], getcurpos()[1:2])
    705  write
    706 
    707  " The commented :au above was moved here so that :mkview (on BufWinLeave) can
    708  " run before :loadview. This is needed because Nvim's :loadview raises E484 if
    709  " the view can't be opened, while Vim's silently fails instead.
    710  au BufWinEnter * silent loadview
    711 
    712  edit Xfile1
    713  call assert_equal([2, 4], getcurpos()[1:2])
    714  edit Xfile2
    715  call assert_equal([2, 6], getcurpos()[1:2])
    716  edit Xfile3
    717  call assert_equal([3, 4], getcurpos()[1:2])
    718 
    719  exe "normal \<C-O>"
    720  call assert_equal('Xfile2', expand('%'))
    721  call assert_equal([2, 6], getcurpos()[1:2])
    722  exe "normal \<C-O>"
    723  call assert_equal('Xfile1', expand('%'))
    724  call assert_equal([2, 4], getcurpos()[1:2])
    725 
    726  au! BufWinLeave
    727  au! BufWinEnter
    728  bwipe!
    729  call delete('Xviewdir', 'rf')
    730  call delete('Xfile1')
    731  call delete('Xfile2')
    732  call delete('Xfile3')
    733  set viewdir&
    734 endfunc
    735 
    736 " A clean session (one empty buffer, one window, and one tab) should not
    737 " set any error messages when sourced because no commands should fail.
    738 func Test_mksession_no_errmsg()
    739  let v:errmsg = ''
    740  %bwipe!
    741  mksession! Xtest_mks.out
    742  source Xtest_mks.out
    743  call assert_equal('', v:errmsg)
    744  call delete('Xtest_mks.out')
    745 endfunc
    746 
    747 func Test_mksession_quote_in_filename()
    748  if !has('unix')
    749    " only Unix can handle this weird filename
    750    return
    751  endif
    752  let v:errmsg = ''
    753  let filename = has('win32') ? 'x''y' : 'x''y"z'
    754  %bwipe!
    755  split another
    756  execute 'split' escape(filename, '"')
    757  mksession! Xtest_mks_quoted.out
    758  %bwipe!
    759  source Xtest_mks_quoted.out
    760  call assert_true(bufexists(filename))
    761 
    762  %bwipe!
    763  call delete('Xtest_mks_quoted.out')
    764 endfunc
    765 
    766 " Test for storing global variables in a session file
    767 func Test_mksession_globals()
    768  set sessionoptions+=globals
    769 
    770  " create different global variables
    771  let g:Global_string = "Sun is shining\r\n"
    772  let g:Global_count = 100
    773  let g:Global_pi = 3.14
    774  let g:Global_neg_float = -2.68
    775 
    776  mksession! Xtest_mks.out
    777 
    778  unlet g:Global_string
    779  unlet g:Global_count
    780  unlet g:Global_pi
    781  unlet g:Global_neg_float
    782 
    783  source Xtest_mks.out
    784  call assert_equal("Sun is shining\r\n", g:Global_string)
    785  call assert_equal(100, g:Global_count)
    786  call assert_equal(3.14, g:Global_pi)
    787  call assert_equal(-2.68, g:Global_neg_float)
    788 
    789  unlet g:Global_string
    790  unlet g:Global_count
    791  unlet g:Global_pi
    792  unlet g:Global_neg_float
    793  call delete('Xtest_mks.out')
    794  set sessionoptions&
    795 endfunc
    796 
    797 " Test for changing backslash to forward slash in filenames
    798 func Test_mksession_slash()
    799  if exists('+shellslash')
    800    throw 'Skipped: cannot use backslash in file name'
    801  endif
    802  enew
    803  %bwipe!
    804  e a\\b\\c
    805  mksession! Xtest_mks1.out
    806  set sessionoptions+=slash
    807  mksession! Xtest_mks2.out
    808 
    809  %bwipe!
    810  source Xtest_mks1.out
    811  call assert_equal('a/b/c', bufname(''))
    812  %bwipe!
    813  source Xtest_mks2.out
    814  call assert_equal('a/b/c', bufname(''))
    815 
    816  %bwipe!
    817  call delete('Xtest_mks1.out')
    818  call delete('Xtest_mks2.out')
    819  set sessionoptions&
    820 endfunc
    821 
    822 " Test for changing directory to the session file directory
    823 func Test_mksession_sesdir()
    824  let save_cwd = getcwd()
    825  call mkdir('Xproj')
    826  mksession! Xproj/Xtest_mks1.out
    827  set sessionoptions-=curdir
    828  set sessionoptions+=sesdir
    829  mksession! Xproj/Xtest_mks2.out
    830 
    831  source Xproj/Xtest_mks1.out
    832  call assert_equal('testdir', fnamemodify(getcwd(), ':t'))
    833  source Xproj/Xtest_mks2.out
    834  call assert_equal('Xproj', fnamemodify(getcwd(), ':t'))
    835  call chdir(save_cwd)
    836  %bwipe
    837 
    838  set sessionoptions&
    839  call delete('Xproj', 'rf')
    840 endfunc
    841 
    842 " Test for saving and restoring the tab-local working directory when there is
    843 " only a single tab and 'tabpages' is not in 'sessionoptions'.
    844 func Test_mksession_tcd_single_tabs()
    845  only | tabonly
    846 
    847  let save_cwd = getcwd()
    848  set sessionoptions-=tabpages
    849  set sessionoptions+=curdir
    850  call mkdir('Xtopdir1')
    851  call mkdir('Xtopdir2')
    852 
    853  " There are two tab pages, the current one has local cwd set to 'Xtopdir2'.
    854  exec 'tcd ' .. save_cwd .. '/Xtopdir1'
    855  tabnew
    856  exec 'tcd ' .. save_cwd .. '/Xtopdir2'
    857  mksession! Xtest_tcd_single
    858 
    859  source Xtest_tcd_single
    860  " call assert_equal(2, haslocaldir())
    861  call assert_equal(1, haslocaldir(-1))
    862  call assert_equal('Xtopdir2', fnamemodify(getcwd(-1, 0), ':t'))
    863  %bwipe
    864 
    865  set sessionoptions&
    866  call chdir(save_cwd)
    867  call delete('Xtopdir1', 'rf')
    868  call delete('Xtopdir2', 'rf')
    869 endfunc
    870 
    871 " Test for storing the 'lines' and 'columns' settings
    872 func Test_mksession_resize()
    873  mksession! Xtest_mks1.out
    874  set sessionoptions+=resize
    875  mksession! Xtest_mks2.out
    876 
    877  let lines = readfile('Xtest_mks1.out')
    878  let found_resize = v:false
    879  for line in lines
    880    if line =~ '^set lines='
    881      let found_resize = v:true
    882      break
    883    endif
    884  endfor
    885  call assert_false(found_resize)
    886  let lines = readfile('Xtest_mks2.out')
    887  let found_resize = v:false
    888  for line in lines
    889    if line =~ '^set lines='
    890      let found_resize = v:true
    891      break
    892    endif
    893  endfor
    894  call assert_true(found_resize)
    895 
    896  call delete('Xtest_mks1.out')
    897  call delete('Xtest_mks2.out')
    898  set sessionoptions&
    899 endfunc
    900 
    901 " Test for mksession with a named scratch buffer
    902 func Test_mksession_scratch()
    903  enew | only
    904  file Xscratch
    905  set buftype=nofile
    906  mksession! Xtest_mks.out
    907  %bwipe
    908  source Xtest_mks.out
    909  call assert_equal('Xscratch', bufname(''))
    910  call assert_equal('nofile', &buftype)
    911  %bwipe
    912  call delete('Xtest_mks.out')
    913 endfunc
    914 
    915 " Test for mksession with fold options
    916 func Test_mksession_foldopt()
    917  set sessionoptions-=options
    918  set sessionoptions+=folds
    919  new
    920  setlocal foldenable
    921  setlocal foldmethod=expr
    922  setlocal foldmarker=<<<,>>>
    923  setlocal foldignore=%
    924  setlocal foldlevel=2
    925  setlocal foldminlines=10
    926  setlocal foldnestmax=15
    927  mksession! Xtest_mks.out
    928  close
    929  %bwipe
    930 
    931  source Xtest_mks.out
    932  call assert_true(&foldenable)
    933  call assert_equal('expr', &foldmethod)
    934  call assert_equal('<<<,>>>', &foldmarker)
    935  call assert_equal('%', &foldignore)
    936  call assert_equal(2, &foldlevel)
    937  call assert_equal(10, &foldminlines)
    938  call assert_equal(15, &foldnestmax)
    939 
    940  close
    941  %bwipe
    942  set sessionoptions&
    943  call delete('Xtest_mks.out')
    944 endfunc
    945 
    946 " Test for mksession with "help" but not "options" in 'sessionoptions'
    947 func Test_mksession_help_noopt()
    948  set sessionoptions-=options
    949  set sessionoptions+=help
    950  help
    951  let fname = expand('%')
    952  mksession! Xtest_mks.out
    953  bwipe
    954 
    955  source Xtest_mks.out
    956  call assert_equal('help', &buftype)
    957  call assert_equal('help', &filetype)
    958  call assert_equal(fname, expand('%'))
    959  call assert_false(&modifiable)
    960  call assert_true(&readonly)
    961 
    962  helpclose
    963  help index
    964  let fname = expand('%')
    965  mksession! Xtest_mks.out
    966  bwipe
    967 
    968  source Xtest_mks.out
    969  call assert_equal('help', &buftype)
    970  call assert_equal(fname, expand('%'))
    971 
    972  call delete('Xtest_mks.out')
    973  set sessionoptions&
    974 endfunc
    975 
    976 " Test for mksession with window position
    977 func Test_mksession_winpos()
    978  if !has('gui_running')
    979    " Only applicable in GUI Vim
    980    return
    981  endif
    982  set sessionoptions+=winpos
    983  mksession! Xtest_mks.out
    984  let found_winpos = v:false
    985  let lines = readfile('Xtest_mks.out')
    986  for line in lines
    987    if line =~ '^winpos '
    988      let found_winpos = v:true
    989      break
    990    endif
    991  endfor
    992  call assert_true(found_winpos)
    993  call delete('Xtest_mks.out')
    994  set sessionoptions&
    995 endfunc
    996 
    997 " Test for mksession without options restores winminheight
    998 func Test_mksession_winminheight()
    999  set sessionoptions-=options
   1000  split
   1001  mksession! Xtest_mks.out
   1002  let found_restore = 0
   1003  let lines = readfile('Xtest_mks.out')
   1004  for line in lines
   1005    if line =~ '= s:save_winmin\(width\|height\)'
   1006      let found_restore += 1
   1007    endif
   1008  endfor
   1009  call assert_equal(2, found_restore)
   1010  call delete('Xtest_mks.out')
   1011  close
   1012  set sessionoptions&
   1013 endfunc
   1014 
   1015 " Test for mksession with and without options restores shortmess
   1016 func Test_mksession_shortmess()
   1017  " Without options
   1018  set sessionoptions-=options
   1019  split
   1020  mksession! Xtest_mks.out
   1021  let found_save = 0
   1022  let found_restore = 0
   1023  let lines = readfile('Xtest_mks.out')
   1024  for line in lines
   1025    let line = trim(line)
   1026 
   1027    if line ==# 'let s:shortmess_save = &shortmess'
   1028      let found_save += 1
   1029    endif
   1030 
   1031    if found_save !=# 0 && line ==# 'let &shortmess = s:shortmess_save'
   1032      let found_restore += 1
   1033    endif
   1034  endfor
   1035  call assert_equal(1, found_save)
   1036  call assert_equal(1, found_restore)
   1037  call delete('Xtest_mks.out')
   1038  close
   1039  set sessionoptions&
   1040 
   1041  " With options
   1042  set sessionoptions+=options
   1043  split
   1044  mksession! Xtest_mks.out
   1045  let found_restore = 0
   1046  let lines = readfile('Xtest_mks.out')
   1047  for line in lines
   1048    if line =~# 's:shortmess_save'
   1049      let found_restore += 1
   1050    endif
   1051  endfor
   1052  call assert_equal(0, found_restore)
   1053  call delete('Xtest_mks.out')
   1054  close
   1055  set sessionoptions&
   1056 endfunc
   1057 
   1058 " Test that when Vim loading session has 'A' in 'shortmess' it does not
   1059 " complain about an existing swapfile.
   1060 func Test_mksession_shortmess_with_A()
   1061  edit Xtestfile
   1062  write
   1063  let fname = swapname('%')
   1064  let cont = readblob(fname)
   1065  set sessionoptions-=options
   1066  mksession Xtestsession
   1067  bwipe!
   1068 
   1069  " Recreate the swap file to pretend the file is being edited
   1070  call writefile(cont, fname, 'D')
   1071  set shortmess+=A
   1072  source Xtestsession
   1073 
   1074  set shortmess&
   1075  set sessionoptions&
   1076  call delete('Xtestsession')
   1077  call delete('Xtestfile')
   1078 endfunc
   1079 
   1080 " Test for mksession with 'compatible' option
   1081 func Test_mksession_compatible()
   1082  throw 'skipped: Nvim does not support "compatible" option'
   1083  mksession! Xtest_mks1.out
   1084  set compatible
   1085  mksession! Xtest_mks2.out
   1086  set nocp
   1087 
   1088  let test_success = v:false
   1089  let lines = readfile('Xtest_mks1.out')
   1090  for line in lines
   1091    if line =~ '^if &cp | set nocp | endif'
   1092      let test_success = v:true
   1093      break
   1094    endif
   1095  endfor
   1096  call assert_true(test_success)
   1097 
   1098  let test_success = v:false
   1099  let lines = readfile('Xtest_mks2.out')
   1100  for line in lines
   1101    if line =~ '^if !&cp | set cp | endif'
   1102      let test_success = v:true
   1103      break
   1104    endif
   1105  endfor
   1106  call assert_true(test_success)
   1107 
   1108  call delete('Xtest_mks1.out')
   1109  call delete('Xtest_mks2.out')
   1110  set compatible&
   1111  set sessionoptions&
   1112 endfunc
   1113 
   1114 func s:ClearMappings()
   1115  mapclear
   1116  omapclear
   1117  mapclear!
   1118  lmapclear
   1119  tmapclear
   1120 endfunc
   1121 
   1122 func Test_mkvimrc()
   1123  let entries = [
   1124        \ ['', 'nothing', '<Nop>'],
   1125        \ ['n', 'normal', 'NORMAL<Up>'],
   1126        \ ['v', 'visual', 'VISUAL<S-Down>'],
   1127        \ ['s', 'select', 'SELECT<C-Left>'],
   1128        \ ['x', 'visualonly', 'VISUALONLY<M-Right>'],
   1129        \ ['o', 'operator', 'OPERATOR'],
   1130        \ ['i', 'insert', 'INSERT'],
   1131        \ ['l', 'lang', 'LANG'],
   1132        \ ['c', 'command', 'COMMAND'],
   1133        \ ['t', 'terminal', 'TERMINAL'],
   1134        \ ]
   1135  for entry in entries
   1136    exe entry[0] .. 'map ' .. entry[1] .. ' ' .. entry[2]
   1137  endfor
   1138 
   1139  mkvimrc Xtestvimrc
   1140 
   1141  call s:ClearMappings()
   1142  for entry in entries
   1143    call assert_equal('', maparg(entry[1], entry[0]))
   1144  endfor
   1145 
   1146  source Xtestvimrc
   1147 
   1148  for entry in entries
   1149    call assert_equal(entry[2], maparg(entry[1], entry[0]))
   1150  endfor
   1151 
   1152  call s:ClearMappings()
   1153 
   1154  " the 'pastetoggle', 'wildchar' and 'wildcharm' option values should be
   1155  " stored as key names in the vimrc file
   1156  " set pastetoggle=<F5>
   1157  set wildchar=<F6>
   1158  set wildcharm=<F7>
   1159  call assert_fails('mkvimrc Xtestvimrc', 'E189: "Xtestvimrc" exists')
   1160  mkvimrc! Xtestvimrc
   1161  " call assert_notequal(-1, index(readfile('Xtestvimrc'), 'set pastetoggle=<F5>'))
   1162  call assert_notequal(-1, index(readfile('Xtestvimrc'), 'set wildchar=<F6>'))
   1163  call assert_notequal(-1, index(readfile('Xtestvimrc'), 'set wildcharm=<F7>'))
   1164  " set pastetoggle& wildchar& wildcharm&
   1165  set wildchar& wildcharm&
   1166 
   1167  call delete('Xtestvimrc')
   1168 endfunc
   1169 
   1170 func Test_scrolloff()
   1171  set sessionoptions+=localoptions
   1172  setlocal so=1 siso=1
   1173  mksession! Xtest_mks.out
   1174  setlocal so=-1 siso=-1
   1175  source Xtest_mks.out
   1176  call assert_equal(1, &l:so)
   1177  call assert_equal(1, &l:siso)
   1178  call delete('Xtest_mks.out')
   1179  setlocal so& siso&
   1180  set sessionoptions&
   1181 endfunc
   1182 
   1183 func Test_altfile()
   1184  edit Xone
   1185  split Xtwo
   1186  edit Xtwoalt
   1187  edit #
   1188  wincmd w
   1189  edit Xonealt
   1190  edit #
   1191  mksession! Xtest_altfile
   1192  only
   1193  bwipe Xonealt
   1194  bwipe Xtwoalt
   1195  bwipe!
   1196  source Xtest_altfile
   1197  call assert_equal('Xone', bufname())
   1198  call assert_equal('Xonealt', bufname('#'))
   1199  wincmd w
   1200  call assert_equal('Xtwo', bufname())
   1201  call assert_equal('Xtwoalt', bufname('#'))
   1202  only
   1203  bwipe!
   1204  call delete('Xtest_altfile')
   1205 endfunc
   1206 
   1207 " Test for creating views with manual folds
   1208 func Test_mkview_manual_fold()
   1209  call writefile(range(1,10), 'Xmkvfile', 'D')
   1210  new Xmkvfile
   1211  " create recursive folds
   1212  5,6fold
   1213  4,7fold
   1214  mkview Xview
   1215  normal zE
   1216  source Xview
   1217  call assert_equal([-1, 4, 4, 4, 4, -1], [foldclosed(3), foldclosed(4),
   1218        \ foldclosed(5), foldclosed(6), foldclosed(7), foldclosed(8)])
   1219  " open one level of fold
   1220  4foldopen
   1221  mkview! Xview
   1222  normal zE
   1223  source Xview
   1224  call assert_equal([-1, -1, 5, 5, -1, -1], [foldclosed(3), foldclosed(4),
   1225        \ foldclosed(5), foldclosed(6), foldclosed(7), foldclosed(8)])
   1226  " open all the folds
   1227  %foldopen!
   1228  mkview! Xview
   1229  normal zE
   1230  source Xview
   1231  call assert_equal([-1, -1, -1, -1, -1, -1], [foldclosed(3), foldclosed(4),
   1232        \ foldclosed(5), foldclosed(6), foldclosed(7), foldclosed(8)])
   1233  call delete('Xview')
   1234  bw!
   1235 endfunc
   1236 
   1237 " Test for handling invalid folds within views
   1238 func Test_mkview_ignore_invalid_folds()
   1239  call writefile(range(1,10), 'Xmkvfile', 'D')
   1240  new Xmkvfile
   1241  " create some folds
   1242  5,6fold
   1243  4,7fold
   1244  mkview Xview
   1245  normal zE
   1246  " delete lines to make folds invalid
   1247  call deletebufline('', 6, '$')
   1248  source Xview
   1249  call assert_equal([-1, -1, -1, -1, -1, -1], [foldclosed(3), foldclosed(4),
   1250        \ foldclosed(5), foldclosed(6), foldclosed(7), foldclosed(8)])
   1251  call delete('Xview')
   1252  bw!
   1253 endfunc
   1254 
   1255 " Test default 'viewdir' value
   1256 func Test_mkview_default_home()
   1257  throw 'Skipped: N/A'
   1258  if has('win32')
   1259    " use escape() to handle backslash path separators
   1260    call assert_match('^' .. escape($ORIGHOME, '\') .. '/vimfiles', &viewdir)
   1261  elseif has('unix')
   1262    call assert_match(
   1263          \ '^' .. $ORIGHOME .. '/.vim\|' ..
   1264          \ '^' .. $XDG_CONFIG_HOME .. '/vim'
   1265          \ , &viewdir)
   1266  elseif has('amiga')
   1267    call assert_match('^home:vimfiles', &viewdir)
   1268  elseif has('mac')
   1269    call assert_match('^' .. $VIM .. '/vimfiles', &viewdir)
   1270  endif
   1271 endfunc
   1272 
   1273 " vim: shiftwidth=2 sts=2 expandtab