neovim

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

cd_spec.lua (10664B)


      1 -- Specs for :cd, :tcd, :lcd and getcwd()
      2 
      3 local t = require('test.testutil')
      4 local n = require('test.functional.testnvim')()
      5 
      6 local eq = t.eq
      7 local call = n.call
      8 local clear = n.clear
      9 local command = n.command
     10 local exc_exec = n.exc_exec
     11 local pathsep = n.get_pathsep()
     12 local skip = t.skip
     13 local is_os = t.is_os
     14 local mkdir = t.mkdir
     15 
     16 -- These directories will be created for testing
     17 local directories = {
     18  tab = 'Xtest-functional-ex_cmds-cd_spec.tab', -- Tab
     19  window = 'Xtest-functional-ex_cmds-cd_spec.window', -- Window
     20  global = 'Xtest-functional-ex_cmds-cd_spec.global', -- New global
     21 }
     22 
     23 -- Shorthand writing to get the current working directory
     24 local cwd = function(...)
     25  return call('getcwd', ...)
     26 end -- effective working dir
     27 local wcwd = function()
     28  return cwd(0)
     29 end -- window dir
     30 local tcwd = function()
     31  return cwd(-1, 0)
     32 end -- tab dir
     33 
     34 -- Same, except these tell us if there is a working directory at all
     35 local lwd = function(...)
     36  return call('haslocaldir', ...)
     37 end -- effective working dir
     38 local wlwd = function()
     39  return lwd(0)
     40 end -- window dir
     41 local tlwd = function()
     42  return lwd(-1, 0)
     43 end -- tab dir
     44 --local glwd = function() return eval('haslocaldir(-1, -1)') end  -- global dir
     45 
     46 -- Test both the `cd` and `chdir` variants
     47 for _, cmd in ipairs { 'cd', 'chdir' } do
     48  describe(':' .. cmd, function()
     49    before_each(function()
     50      clear()
     51      for _, d in pairs(directories) do
     52        mkdir(d)
     53      end
     54      directories.start = cwd()
     55    end)
     56 
     57    after_each(function()
     58      for _, d in pairs(directories) do
     59        vim.uv.fs_rmdir(d)
     60      end
     61    end)
     62 
     63    describe('using explicit scope', function()
     64      it('for window', function()
     65        local globalDir = directories.start
     66        local globalwin = call('winnr')
     67        local tabnr = call('tabpagenr')
     68 
     69        -- Everything matches globalDir to start
     70        eq(globalDir, cwd(globalwin))
     71        eq(globalDir, cwd(globalwin, tabnr))
     72        eq(0, lwd(globalwin))
     73        eq(0, lwd(globalwin, tabnr))
     74 
     75        command('bot split')
     76        local localwin = call('winnr')
     77        -- Initial window is still using globalDir
     78        eq(globalDir, cwd(localwin))
     79        eq(globalDir, cwd(localwin, tabnr))
     80        eq(0, lwd(globalwin))
     81        eq(0, lwd(globalwin, tabnr))
     82 
     83        command('silent l' .. cmd .. ' ' .. directories.window)
     84        -- From window with local dir, the original window
     85        -- is still reporting the global dir
     86        eq(globalDir, cwd(globalwin))
     87        eq(globalDir, cwd(globalwin, tabnr))
     88        eq(0, lwd(globalwin))
     89        eq(0, lwd(globalwin, tabnr))
     90 
     91        -- Window with local dir reports as such
     92        eq(globalDir .. pathsep .. directories.window, cwd(localwin))
     93        eq(globalDir .. pathsep .. directories.window, cwd(localwin, tabnr))
     94        eq(1, lwd(localwin))
     95        eq(1, lwd(localwin, tabnr))
     96 
     97        command('tabnew')
     98        -- From new tab page, original window reports global dir
     99        eq(globalDir, cwd(globalwin, tabnr))
    100        eq(0, lwd(globalwin, tabnr))
    101 
    102        -- From new tab page, local window reports as such
    103        eq(globalDir .. pathsep .. directories.window, cwd(localwin, tabnr))
    104        eq(1, lwd(localwin, tabnr))
    105      end)
    106 
    107      it('for tab page', function()
    108        local globalDir = directories.start
    109        local globaltab = call('tabpagenr')
    110 
    111        -- Everything matches globalDir to start
    112        eq(globalDir, cwd(-1, 0))
    113        eq(globalDir, cwd(-1, globaltab))
    114        eq(0, lwd(-1, 0))
    115        eq(0, lwd(-1, globaltab))
    116 
    117        command('tabnew')
    118        command('silent t' .. cmd .. ' ' .. directories.tab)
    119        local localtab = call('tabpagenr')
    120 
    121        -- From local tab page, original tab reports globalDir
    122        eq(globalDir, cwd(-1, globaltab))
    123        eq(0, lwd(-1, globaltab))
    124 
    125        -- new tab reports local
    126        eq(globalDir .. pathsep .. directories.tab, cwd(-1, 0))
    127        eq(globalDir .. pathsep .. directories.tab, cwd(-1, localtab))
    128        eq(1, lwd(-1, 0))
    129        eq(1, lwd(-1, localtab))
    130 
    131        command('tabnext')
    132        -- From original tab page, local reports as such
    133        eq(globalDir .. pathsep .. directories.tab, cwd(-1, localtab))
    134        eq(1, lwd(-1, localtab))
    135      end)
    136    end)
    137 
    138    describe('getcwd(-1, -1)', function()
    139      it('works', function()
    140        eq(directories.start, cwd(-1, -1))
    141        eq(0, lwd(-1, -1))
    142      end)
    143 
    144      it('works with tab-local pwd', function()
    145        command('silent t' .. cmd .. ' ' .. directories.tab)
    146        eq(directories.start, cwd(-1, -1))
    147        eq(0, lwd(-1, -1))
    148      end)
    149 
    150      it('works with window-local pwd', function()
    151        command('silent l' .. cmd .. ' ' .. directories.window)
    152        eq(directories.start, cwd(-1, -1))
    153        eq(0, lwd(-1, -1))
    154      end)
    155    end)
    156 
    157    describe('Local directory gets inherited', function()
    158      it('by tabs', function()
    159        local globalDir = directories.start
    160 
    161        -- Create a new tab and change directory
    162        command('tabnew')
    163        command('silent t' .. cmd .. ' ' .. directories.tab)
    164        eq(globalDir .. pathsep .. directories.tab, tcwd())
    165 
    166        -- Create a new tab and verify it has inherited the directory
    167        command('tabnew')
    168        eq(globalDir .. pathsep .. directories.tab, tcwd())
    169 
    170        -- Change tab and change back, verify that directories are correct
    171        command('tabnext')
    172        eq(globalDir, tcwd())
    173        command('tabprevious')
    174        eq(globalDir .. pathsep .. directories.tab, tcwd())
    175      end)
    176    end)
    177 
    178    it('works', function()
    179      local globalDir = directories.start
    180      -- Create a new tab first and verify that is has the same working dir
    181      command('tabnew')
    182      eq(globalDir, cwd())
    183      eq(globalDir, tcwd()) -- has no tab-local directory
    184      eq(0, tlwd())
    185      eq(globalDir, wcwd()) -- has no window-local directory
    186      eq(0, wlwd())
    187 
    188      -- Change tab-local working directory and verify it is different
    189      command('silent t' .. cmd .. ' ' .. directories.tab)
    190      eq(globalDir .. pathsep .. directories.tab, cwd())
    191      eq(cwd(), tcwd()) -- working directory matches tab directory
    192      eq(1, tlwd())
    193      eq(cwd(), wcwd()) -- still no window-directory
    194      eq(0, wlwd())
    195 
    196      -- Create a new window in this tab to test `:lcd`
    197      command('new')
    198      eq(1, tlwd()) -- Still tab-local working directory
    199      eq(0, wlwd()) -- Still no window-local working directory
    200      eq(globalDir .. pathsep .. directories.tab, cwd())
    201      command('silent l' .. cmd .. ' ../' .. directories.window)
    202      eq(globalDir .. pathsep .. directories.window, cwd())
    203      eq(globalDir .. pathsep .. directories.tab, tcwd())
    204      eq(1, wlwd())
    205 
    206      -- Verify the first window still has the tab local directory
    207      command('wincmd w')
    208      eq(globalDir .. pathsep .. directories.tab, cwd())
    209      eq(globalDir .. pathsep .. directories.tab, tcwd())
    210      eq(0, wlwd()) -- No window-local directory
    211 
    212      -- Change back to initial tab and verify working directory has stayed
    213      command('tabnext')
    214      eq(globalDir, cwd())
    215      eq(0, tlwd())
    216      eq(0, wlwd())
    217 
    218      -- Verify global changes don't affect local ones
    219      command('silent ' .. cmd .. ' ' .. directories.global)
    220      eq(globalDir .. pathsep .. directories.global, cwd())
    221      command('tabnext')
    222      eq(globalDir .. pathsep .. directories.tab, cwd())
    223      eq(globalDir .. pathsep .. directories.tab, tcwd())
    224      eq(0, wlwd()) -- Still no window-local directory in this window
    225 
    226      -- Unless the global change happened in a tab with local directory
    227      command('silent ' .. cmd .. ' ..')
    228      eq(globalDir, cwd())
    229      eq(0, tlwd())
    230      eq(0, wlwd())
    231      -- Which also affects the first tab
    232      command('tabnext')
    233      eq(globalDir, cwd())
    234 
    235      -- But not in a window with its own local directory
    236      command('tabnext | wincmd w')
    237      eq(globalDir .. pathsep .. directories.window, cwd())
    238      eq(0, tlwd())
    239      eq(globalDir .. pathsep .. directories.window, wcwd())
    240    end)
    241  end)
    242 end
    243 
    244 -- Test legal parameters for 'getcwd' and 'haslocaldir'
    245 for _, cmd in ipairs { 'getcwd', 'haslocaldir' } do
    246  describe(cmd .. '()', function()
    247    before_each(function()
    248      clear()
    249    end)
    250 
    251    -- Test invalid argument types
    252    local err474 = 'Vim(call):E474: Invalid argument'
    253    it('fails on string', function()
    254      eq(err474, exc_exec('call ' .. cmd .. '("some string")'))
    255    end)
    256    it('fails on float', function()
    257      eq(err474, exc_exec('call ' .. cmd .. '(1.0)'))
    258    end)
    259    it('fails on list', function()
    260      eq(err474, exc_exec('call ' .. cmd .. '([1, 2])'))
    261    end)
    262    it('fails on dictionary', function()
    263      eq(err474, exc_exec('call ' .. cmd .. '({"key": "value"})'))
    264    end)
    265    it('fails on funcref', function()
    266      eq(err474, exc_exec('call ' .. cmd .. '(function("tr"))'))
    267    end)
    268 
    269    -- Test invalid numbers
    270    it('fails on number less than -1', function()
    271      eq(err474, exc_exec('call ' .. cmd .. '(-2)'))
    272    end)
    273    local err5001 = 'Vim(call):E5001: Higher scope cannot be -1 if lower scope is >= 0.'
    274    it('fails on -1 if previous arg is >=0', function()
    275      eq(err5001, exc_exec('call ' .. cmd .. '(0, -1)'))
    276    end)
    277 
    278    -- Test wrong number of arguments
    279    local err118 = 'Vim(call):E118: Too many arguments for function: ' .. cmd
    280    it('fails to parse more than one argument', function()
    281      eq(err118, exc_exec('call ' .. cmd .. '(0, 0, 0)'))
    282    end)
    283  end)
    284 end
    285 
    286 describe('getcwd()', function()
    287  before_each(function()
    288    clear()
    289    mkdir(directories.global)
    290  end)
    291 
    292  after_each(function()
    293    n.rmdir(directories.global)
    294  end)
    295 
    296  it('returns empty string if working directory does not exist', function()
    297    skip(is_os('win'), 'N/A for Windows')
    298    command('cd ' .. directories.global)
    299    command("call delete('../" .. directories.global .. "', 'd')")
    300    eq('', n.eval('getcwd()'))
    301  end)
    302 
    303  it("works with 'autochdir' after local directory was set (#9892)", function()
    304    local curdir = cwd()
    305    command('lcd ' .. directories.global)
    306    command('lcd -')
    307    command('set autochdir')
    308    command('edit ' .. directories.global .. '/foo')
    309    eq(curdir .. pathsep .. directories.global, cwd())
    310    eq(curdir, wcwd())
    311    call('mkdir', 'bar')
    312    command('edit ' .. 'bar/foo')
    313    eq(curdir .. pathsep .. directories.global .. pathsep .. 'bar', cwd())
    314    eq(curdir, wcwd())
    315    command('lcd ..')
    316    eq(curdir .. pathsep .. directories.global, cwd())
    317    eq(curdir .. pathsep .. directories.global, wcwd())
    318    command('edit')
    319    eq(curdir .. pathsep .. directories.global .. pathsep .. 'bar', cwd())
    320    eq(curdir .. pathsep .. directories.global, wcwd())
    321  end)
    322 end)