mksession_spec.lua 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. local t = require('test.testutil')
  2. local n = require('test.functional.testnvim')()
  3. local Screen = require('test.functional.ui.screen')
  4. local clear = n.clear
  5. local command = n.command
  6. local get_pathsep = n.get_pathsep
  7. local eq = t.eq
  8. local neq = t.neq
  9. local fn = n.fn
  10. local matches = t.matches
  11. local pesc = vim.pesc
  12. local rmdir = n.rmdir
  13. local sleep = vim.uv.sleep
  14. local api = n.api
  15. local skip = t.skip
  16. local is_os = t.is_os
  17. local mkdir = t.mkdir
  18. local file_prefix = 'Xtest-functional-ex_cmds-mksession_spec'
  19. describe(':mksession', function()
  20. local session_file = file_prefix .. '.vim'
  21. local tab_dir = file_prefix .. '.d'
  22. before_each(function()
  23. clear()
  24. mkdir(tab_dir)
  25. end)
  26. after_each(function()
  27. os.remove(session_file)
  28. rmdir(tab_dir)
  29. end)
  30. it('restores same :terminal buf in splits', function()
  31. -- If the same :terminal is displayed in multiple windows, :mksession
  32. -- should restore it as such.
  33. -- Create three windows: first two from top show same terminal, third -
  34. -- another one (created earlier).
  35. command('terminal')
  36. command('split')
  37. command('terminal')
  38. command('split')
  39. command('mksession ' .. session_file)
  40. command('%bwipeout!')
  41. -- Create a new test instance of Nvim.
  42. clear()
  43. -- Restore session.
  44. command('source ' .. session_file)
  45. eq(fn.winbufnr(1), fn.winbufnr(2))
  46. neq(fn.winbufnr(1), fn.winbufnr(3))
  47. end)
  48. -- common testing procedure for testing "sessionoptions-=terminal"
  49. local function test_terminal_session_disabled(expected_buf_count)
  50. command('set sessionoptions-=terminal')
  51. command('mksession ' .. session_file)
  52. -- Create a new test instance of Nvim.
  53. clear()
  54. -- Restore session.
  55. command('source ' .. session_file)
  56. eq(expected_buf_count, #api.nvim_list_bufs())
  57. end
  58. it('do not restore :terminal if not set in sessionoptions, terminal in curwin #13078', function()
  59. local tmpfile_base = file_prefix .. '-tmpfile'
  60. command('edit ' .. tmpfile_base)
  61. command('terminal')
  62. local buf_count = #api.nvim_list_bufs()
  63. eq(2, buf_count)
  64. eq('terminal', api.nvim_get_option_value('buftype', {}))
  65. test_terminal_session_disabled(2)
  66. -- no terminal should be set. As a side effect we end up with a blank buffer
  67. eq('', api.nvim_get_option_value('buftype', { buf = api.nvim_list_bufs()[1] }))
  68. eq('', api.nvim_get_option_value('buftype', { buf = api.nvim_list_bufs()[2] }))
  69. end)
  70. it('do not restore :terminal if not set in sessionoptions, terminal hidden #13078', function()
  71. command('terminal')
  72. local terminal_bufnr = api.nvim_get_current_buf()
  73. local tmpfile_base = file_prefix .. '-tmpfile'
  74. -- make terminal hidden by opening a new file
  75. command('edit ' .. tmpfile_base .. '1')
  76. local buf_count = #api.nvim_list_bufs()
  77. eq(2, buf_count)
  78. eq(1, fn.getbufinfo(terminal_bufnr)[1].hidden)
  79. test_terminal_session_disabled(1)
  80. -- no terminal should exist here
  81. neq('', api.nvim_buf_get_name(api.nvim_list_bufs()[1]))
  82. end)
  83. it('do not restore :terminal if not set in sessionoptions, only buffer #13078', function()
  84. command('terminal')
  85. eq('terminal', api.nvim_get_option_value('buftype', {}))
  86. local buf_count = #api.nvim_list_bufs()
  87. eq(1, buf_count)
  88. test_terminal_session_disabled(1)
  89. -- no terminal should be set
  90. eq('', api.nvim_get_option_value('buftype', {}))
  91. end)
  92. it('restores tab-local working directories', function()
  93. local tmpfile_base = file_prefix .. '-tmpfile'
  94. local cwd_dir = fn.getcwd()
  95. -- :mksession does not save empty tabs, so create some buffers.
  96. command('edit ' .. tmpfile_base .. '1')
  97. command('tabnew')
  98. command('edit ' .. tmpfile_base .. '2')
  99. command('tcd ' .. tab_dir)
  100. command('tabfirst')
  101. command('mksession ' .. session_file)
  102. -- Create a new test instance of Nvim.
  103. clear()
  104. command('source ' .. session_file)
  105. -- First tab should have the original working directory.
  106. command('tabnext 1')
  107. eq(cwd_dir, fn.getcwd())
  108. -- Second tab should have the tab-local working directory.
  109. command('tabnext 2')
  110. eq(cwd_dir .. get_pathsep() .. tab_dir, fn.getcwd())
  111. end)
  112. it('restores buffers with tab-local CWD', function()
  113. local tmpfile_base = file_prefix .. '-tmpfile'
  114. local cwd_dir = fn.getcwd()
  115. local session_path = cwd_dir .. get_pathsep() .. session_file
  116. command('edit ' .. tmpfile_base .. '1')
  117. command('tcd ' .. tab_dir)
  118. command('tabnew')
  119. command('edit ' .. cwd_dir .. get_pathsep() .. tmpfile_base .. '2')
  120. command('tabfirst')
  121. command('mksession ' .. session_path)
  122. -- Create a new test instance of Nvim.
  123. clear()
  124. -- Use :silent to avoid press-enter prompt due to long path
  125. command('silent source ' .. session_path)
  126. command('tabnext 1')
  127. eq(cwd_dir .. get_pathsep() .. tmpfile_base .. '1', fn.expand('%:p'))
  128. command('tabnext 2')
  129. eq(cwd_dir .. get_pathsep() .. tmpfile_base .. '2', fn.expand('%:p'))
  130. end)
  131. it('restores CWD for :terminal buffers #11288', function()
  132. skip(is_os('win'), 'causes rmdir() to fail')
  133. local cwd_dir = fn.fnamemodify('.', ':p:~'):gsub([[[\/]*$]], '')
  134. cwd_dir = t.fix_slashes(cwd_dir) -- :mksession always uses unix slashes.
  135. local session_path = cwd_dir .. '/' .. session_file
  136. command('cd ' .. tab_dir)
  137. command('terminal')
  138. command('cd ' .. cwd_dir)
  139. command('mksession ' .. session_path)
  140. command('%bwipeout!')
  141. if is_os('win') then
  142. sleep(100) -- Make sure all child processes have exited.
  143. end
  144. -- Create a new test instance of Nvim.
  145. clear()
  146. command('silent source ' .. session_path)
  147. local expected_cwd = cwd_dir .. '/' .. tab_dir
  148. matches('^term://' .. pesc(expected_cwd) .. '//%d+:', fn.expand('%'))
  149. command('%bwipeout!')
  150. if is_os('win') then
  151. sleep(100) -- Make sure all child processes have exited.
  152. end
  153. end)
  154. it('restores CWD for :terminal buffer at root directory #16988', function()
  155. skip(is_os('win'), 'N/A for Windows')
  156. local screen
  157. local cwd_dir = fn.fnamemodify('.', ':p:~'):gsub([[[\/]*$]], '')
  158. local session_path = cwd_dir .. '/' .. session_file
  159. screen = Screen.new(50, 6, { rgb = false })
  160. local expected_screen = [[
  161. ^/ |
  162. |
  163. [Process exited 0] |
  164. |*3
  165. ]]
  166. command('cd /')
  167. command('terminal echo $PWD')
  168. -- Verify that the terminal's working directory is "/".
  169. screen:expect(expected_screen)
  170. command('cd ' .. cwd_dir)
  171. command('mksession ' .. session_path)
  172. command('%bwipeout!')
  173. -- Create a new test instance of Nvim.
  174. clear()
  175. screen = Screen.new(50, 6, { rgb = false })
  176. command('silent source ' .. session_path)
  177. -- Verify that the terminal's working directory is "/".
  178. screen:expect(expected_screen)
  179. end)
  180. it('restores a session when there is a float #18432', function()
  181. local tmpfile = file_prefix .. '-tmpfile-float'
  182. command('edit ' .. tmpfile)
  183. local buf = api.nvim_create_buf(false, true)
  184. local config = {
  185. relative = 'editor',
  186. focusable = false,
  187. width = 10,
  188. height = 3,
  189. row = 0,
  190. col = 1,
  191. style = 'minimal',
  192. }
  193. api.nvim_open_win(buf, false, config)
  194. local cmdheight = api.nvim_get_option_value('cmdheight', {})
  195. command('mksession ' .. session_file)
  196. -- Create a new test instance of Nvim.
  197. clear()
  198. command('source ' .. session_file)
  199. eq(tmpfile, fn.expand('%'))
  200. -- Check that there is only a single window, which indicates the floating
  201. -- window was not restored.
  202. eq(1, fn.winnr('$'))
  203. -- The command-line height should remain the same as it was.
  204. eq(cmdheight, api.nvim_get_option_value('cmdheight', {}))
  205. os.remove(tmpfile)
  206. end)
  207. end)