neovim

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

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)