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