mirror of
				https://github.com/neovim/neovim.git
				synced 2025-10-26 12:27:24 +00:00 
			
		
		
		
	 052498ed42
			
		
	
	052498ed42
	
	
	
		
			
			Specifically, functions that are run in the context of the test runner are put in module `test/testutil.lua` while the functions that are run in the context of the test session are put in `test/functional/testnvim.lua`. Closes https://github.com/neovim/neovim/issues/27004.
		
			
				
	
	
		
			1426 lines
		
	
	
		
			40 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			1426 lines
		
	
	
		
			40 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
| local t = require('test.testutil')
 | |
| local n = require('test.functional.testnvim')()
 | |
| local Screen = require('test.functional.ui.screen')
 | |
| 
 | |
| local assert_alive = n.assert_alive
 | |
| local assert_log = t.assert_log
 | |
| local clear = n.clear
 | |
| local command = n.command
 | |
| local ok = t.ok
 | |
| local eq = t.eq
 | |
| local matches = t.matches
 | |
| local eval = n.eval
 | |
| local exec = n.exec
 | |
| local exec_capture = n.exec_capture
 | |
| local exec_lua = n.exec_lua
 | |
| local feed = n.feed
 | |
| local fn = n.fn
 | |
| local pesc = vim.pesc
 | |
| local mkdir = t.mkdir
 | |
| local mkdir_p = n.mkdir_p
 | |
| local nvim_prog = n.nvim_prog
 | |
| local nvim_set = n.nvim_set
 | |
| local read_file = t.read_file
 | |
| local retry = t.retry
 | |
| local rmdir = n.rmdir
 | |
| local sleep = vim.uv.sleep
 | |
| local startswith = vim.startswith
 | |
| local write_file = t.write_file
 | |
| local api = n.api
 | |
| local alter_slashes = n.alter_slashes
 | |
| local is_os = t.is_os
 | |
| local dedent = t.dedent
 | |
| local tbl_map = vim.tbl_map
 | |
| local tbl_filter = vim.tbl_filter
 | |
| local endswith = vim.endswith
 | |
| local check_close = n.check_close
 | |
| 
 | |
| local testlog = 'Xtest-startupspec-log'
 | |
| 
 | |
| describe('startup', function()
 | |
|   it('--clean', function()
 | |
|     clear()
 | |
|     ok(
 | |
|       string.find(
 | |
|         alter_slashes(api.nvim_get_option_value('runtimepath', {})),
 | |
|         fn.stdpath('config'),
 | |
|         1,
 | |
|         true
 | |
|       ) ~= nil
 | |
|     )
 | |
|     clear('--clean')
 | |
|     ok(
 | |
|       string.find(
 | |
|         alter_slashes(api.nvim_get_option_value('runtimepath', {})),
 | |
|         fn.stdpath('config'),
 | |
|         1,
 | |
|         true
 | |
|       ) == nil
 | |
|     )
 | |
|   end)
 | |
| 
 | |
|   it('prevents remote UI infinite loop', function()
 | |
|     clear()
 | |
|     local screen
 | |
|     screen = Screen.new(84, 3)
 | |
|     screen:attach()
 | |
|     fn.termopen({ nvim_prog, '-u', 'NONE', '--server', eval('v:servername'), '--remote-ui' })
 | |
|     screen:expect([[
 | |
|       ^Cannot attach UI of :terminal child to its parent. (Unset $NVIM to skip this check) |
 | |
|                                                                                           |*2
 | |
|     ]])
 | |
|   end)
 | |
| 
 | |
|   it('--startuptime', function()
 | |
|     local testfile = 'Xtest_startuptime'
 | |
|     finally(function()
 | |
|       os.remove(testfile)
 | |
|     end)
 | |
|     clear({ args = { '--startuptime', testfile } })
 | |
|     assert_log('Embedded', testfile, 100)
 | |
|     assert_log('sourcing', testfile, 100)
 | |
|     assert_log("require%('vim%._editor'%)", testfile, 100)
 | |
|   end)
 | |
| 
 | |
|   it('-D does not hang #12647', function()
 | |
|     clear()
 | |
|     local screen
 | |
|     screen = Screen.new(60, 7)
 | |
|     screen:attach()
 | |
|     -- not the same colors on windows for some reason
 | |
|     screen._default_attr_ids = nil
 | |
|     local id = fn.termopen({
 | |
|       nvim_prog,
 | |
|       '-u',
 | |
|       'NONE',
 | |
|       '-i',
 | |
|       'NONE',
 | |
|       '--cmd',
 | |
|       'set noruler',
 | |
|       '-D',
 | |
|     }, {
 | |
|       env = {
 | |
|         VIMRUNTIME = os.getenv('VIMRUNTIME'),
 | |
|       },
 | |
|     })
 | |
|     screen:expect({ any = pesc('Entering Debug mode.  Type "cont" to continue.') })
 | |
|     fn.chansend(id, 'cont\n')
 | |
|     screen:expect([[
 | |
|       ^                                                            |
 | |
|       ~                                                           |*3
 | |
|       [No Name]                                                   |
 | |
|                                                                   |*2
 | |
|     ]])
 | |
|   end)
 | |
| end)
 | |
| 
 | |
| describe('startup', function()
 | |
|   before_each(clear)
 | |
| 
 | |
|   after_each(function()
 | |
|     check_close()
 | |
|     os.remove(testlog)
 | |
|   end)
 | |
| 
 | |
|   describe('-l Lua', function()
 | |
|     local function assert_l_out(expected, nvim_args, lua_args, script, input)
 | |
|       local args = { nvim_prog }
 | |
|       vim.list_extend(args, nvim_args or {})
 | |
|       vim.list_extend(args, { '-l', (script or 'test/functional/fixtures/startup.lua') })
 | |
|       vim.list_extend(args, lua_args or {})
 | |
|       local out = fn.system(args, input):gsub('\r\n', '\n')
 | |
|       return eq(dedent(expected), out)
 | |
|     end
 | |
| 
 | |
|     it('failure modes', function()
 | |
|       -- nvim -l <empty>
 | |
|       matches('nvim%.?e?x?e?: Argument missing after: "%-l"', fn.system({ nvim_prog, '-l' }))
 | |
|       eq(1, eval('v:shell_error'))
 | |
|     end)
 | |
| 
 | |
|     it('os.exit() sets Nvim exitcode', function()
 | |
|       -- tricky: LeakSanitizer triggers on os.exit() and disrupts the return value, disable it
 | |
|       exec_lua [[
 | |
|         local asan_options = os.getenv('ASAN_OPTIONS') or ''
 | |
|         if asan_options ~= '' then
 | |
|           asan_options = asan_options .. ':'
 | |
|         end
 | |
|         vim.uv.os_setenv('ASAN_OPTIONS', asan_options .. ':detect_leaks=0')
 | |
|       ]]
 | |
|       -- nvim -l foo.lua -arg1 -- a b c
 | |
|       assert_l_out(
 | |
|         [[
 | |
|           bufs:
 | |
|           nvim args: 7
 | |
|           lua args: { "-arg1", "--exitcode", "73", "--arg2",
 | |
|             [0] = "test/functional/fixtures/startup.lua"
 | |
|           }]],
 | |
|         {},
 | |
|         { '-arg1', '--exitcode', '73', '--arg2' }
 | |
|       )
 | |
|       eq(73, eval('v:shell_error'))
 | |
|     end)
 | |
| 
 | |
|     it('Lua-error sets Nvim exitcode', function()
 | |
|       eq(0, eval('v:shell_error'))
 | |
|       matches(
 | |
|         'E5113: .* my pearls!!',
 | |
|         fn.system({ nvim_prog, '-l', 'test/functional/fixtures/startup-fail.lua' })
 | |
|       )
 | |
|       eq(1, eval('v:shell_error'))
 | |
|       matches(
 | |
|         'E5113: .* %[string "error%("whoa"%)"%]:1: whoa',
 | |
|         fn.system({ nvim_prog, '-l', '-' }, 'error("whoa")')
 | |
|       )
 | |
|       eq(1, eval('v:shell_error'))
 | |
|     end)
 | |
| 
 | |
|     it('executes stdin "-"', function()
 | |
|       assert_l_out(
 | |
|         'arg0=- args=2 whoa\n',
 | |
|         nil,
 | |
|         { 'arg1', 'arg 2' },
 | |
|         '-',
 | |
|         "print(('arg0=%s args=%d %s'):format(_G.arg[0], #_G.arg, 'whoa'))"
 | |
|       )
 | |
|       assert_l_out(
 | |
|         'biiig input: 1000042\n',
 | |
|         nil,
 | |
|         nil,
 | |
|         '-',
 | |
|         ('print("biiig input: "..("%s"):len())'):format(string.rep('x', (1000 * 1000) + 42))
 | |
|       )
 | |
|       eq(0, eval('v:shell_error'))
 | |
|     end)
 | |
| 
 | |
|     it('does not truncate long print() message', function()
 | |
|       assert_l_out(('k'):rep(1234) .. '\n', nil, nil, '-', "print(('k'):rep(1234))")
 | |
|     end)
 | |
| 
 | |
|     it('does not add newline when unnecessary', function()
 | |
|       assert_l_out('', nil, nil, '-', '')
 | |
|       assert_l_out('foobar\n', nil, nil, '-', [[print('foobar\n')]])
 | |
|     end)
 | |
| 
 | |
|     it('sets _G.arg', function()
 | |
|       -- nvim -l foo.lua
 | |
|       assert_l_out(
 | |
|         [[
 | |
|           bufs:
 | |
|           nvim args: 3
 | |
|           lua args: {
 | |
|             [0] = "test/functional/fixtures/startup.lua"
 | |
|           }
 | |
|           ]],
 | |
|         {},
 | |
|         {}
 | |
|       )
 | |
|       eq(0, eval('v:shell_error'))
 | |
| 
 | |
|       -- nvim -l foo.lua [args]
 | |
|       assert_l_out(
 | |
|         [[
 | |
|           bufs:
 | |
|           nvim args: 7
 | |
|           lua args: { "-arg1", "--arg2", "--", "arg3",
 | |
|             [0] = "test/functional/fixtures/startup.lua"
 | |
|           }
 | |
|           ]],
 | |
|         {},
 | |
|         { '-arg1', '--arg2', '--', 'arg3' }
 | |
|       )
 | |
|       eq(0, eval('v:shell_error'))
 | |
| 
 | |
|       -- nvim file1 file2 -l foo.lua -arg1 -- file3 file4
 | |
|       assert_l_out(
 | |
|         [[
 | |
|           bufs: file1 file2
 | |
|           nvim args: 10
 | |
|           lua args: { "-arg1", "arg 2", "--", "file3", "file4",
 | |
|             [0] = "test/functional/fixtures/startup.lua"
 | |
|           }
 | |
|           ]],
 | |
|         { 'file1', 'file2' },
 | |
|         { '-arg1', 'arg 2', '--', 'file3', 'file4' }
 | |
|       )
 | |
|       eq(0, eval('v:shell_error'))
 | |
| 
 | |
|       -- nvim -l foo.lua <vim args>
 | |
|       assert_l_out(
 | |
|         [[
 | |
|           bufs:
 | |
|           nvim args: 5
 | |
|           lua args: { "-c", "set wrap?",
 | |
|             [0] = "test/functional/fixtures/startup.lua"
 | |
|           }
 | |
|           ]],
 | |
|         {},
 | |
|         { '-c', 'set wrap?' }
 | |
|       )
 | |
|       eq(0, eval('v:shell_error'))
 | |
| 
 | |
|       -- nvim <vim args> -l foo.lua <vim args>
 | |
|       assert_l_out(
 | |
|         -- luacheck: ignore 611 (Line contains only whitespaces)
 | |
|         [[
 | |
|             wrap
 | |
|           
 | |
|           bufs:
 | |
|           nvim args: 7
 | |
|           lua args: { "-c", "set wrap?",
 | |
|             [0] = "test/functional/fixtures/startup.lua"
 | |
|           }
 | |
|           ]],
 | |
|         { '-c', 'set wrap?' },
 | |
|         { '-c', 'set wrap?' }
 | |
|       )
 | |
|       eq(0, eval('v:shell_error'))
 | |
|     end)
 | |
| 
 | |
|     it('disables swapfile/shada/config/plugins', function()
 | |
|       assert_l_out(
 | |
|         'updatecount=0 shadafile=NONE loadplugins=false scripts=1\n',
 | |
|         nil,
 | |
|         nil,
 | |
|         '-',
 | |
|         [[print(('updatecount=%d shadafile=%s loadplugins=%s scripts=%d'):format(
 | |
|           vim.o.updatecount, vim.o.shadafile, tostring(vim.o.loadplugins), math.max(1, #vim.fn.getscriptinfo())))]]
 | |
|       )
 | |
|     end)
 | |
|   end)
 | |
| 
 | |
|   it('--cmd/-c/+ do not truncate long Lua print() message with --headless', function()
 | |
|     local out = fn.system({
 | |
|       nvim_prog,
 | |
|       '-u',
 | |
|       'NONE',
 | |
|       '-i',
 | |
|       'NONE',
 | |
|       '--headless',
 | |
|       '--cmd',
 | |
|       'lua print(("A"):rep(1234))',
 | |
|       '-c',
 | |
|       'lua print(("B"):rep(1234))',
 | |
|       '+lua print(("C"):rep(1234))',
 | |
|       '+q',
 | |
|     })
 | |
|     eq(('A'):rep(1234) .. '\r\n' .. ('B'):rep(1234) .. '\r\n' .. ('C'):rep(1234), out)
 | |
|   end)
 | |
| 
 | |
|   it('pipe at both ends: has("ttyin")==0 has("ttyout")==0', function()
 | |
|     -- system() puts a pipe at both ends.
 | |
|     local out = fn.system({
 | |
|       nvim_prog,
 | |
|       '-u',
 | |
|       'NONE',
 | |
|       '-i',
 | |
|       'NONE',
 | |
|       '--headless',
 | |
|       '--cmd',
 | |
|       nvim_set,
 | |
|       '-c',
 | |
|       [[echo has('ttyin') has('ttyout')]],
 | |
|       '+q',
 | |
|     })
 | |
|     eq('0 0', out)
 | |
|   end)
 | |
| 
 | |
|   it('with --embed: has("ttyin")==0 has("ttyout")==0', function()
 | |
|     local screen = Screen.new(25, 3)
 | |
|     -- Remote UI connected by --embed.
 | |
|     screen:attach()
 | |
|     -- TODO: a lot of tests in this file already use the new default color scheme.
 | |
|     -- once we do the batch update of tests to use it, remove this workarond
 | |
|     screen._default_attr_ids = nil
 | |
|     command([[echo has('ttyin') has('ttyout')]])
 | |
|     screen:expect([[
 | |
|       ^                         |
 | |
|       ~                        |
 | |
|       0 0                      |
 | |
|     ]])
 | |
|   end)
 | |
| 
 | |
|   it('in a TTY: has("ttyin")==1 has("ttyout")==1', function()
 | |
|     local screen = Screen.new(25, 4)
 | |
|     screen:attach()
 | |
|     screen._default_attr_ids = nil
 | |
|     if is_os('win') then
 | |
|       command([[set shellcmdflag=/s\ /c shellxquote=\"]])
 | |
|     end
 | |
|     -- Running in :terminal
 | |
|     fn.termopen({
 | |
|       nvim_prog,
 | |
|       '-u',
 | |
|       'NONE',
 | |
|       '-i',
 | |
|       'NONE',
 | |
|       '--cmd',
 | |
|       nvim_set,
 | |
|       '-c',
 | |
|       'echo has("ttyin") has("ttyout")',
 | |
|     }, {
 | |
|       env = {
 | |
|         VIMRUNTIME = os.getenv('VIMRUNTIME'),
 | |
|       },
 | |
|     })
 | |
|     screen:expect([[
 | |
|       ^                         |
 | |
|       ~                        |
 | |
|       1 1                      |
 | |
|                                |
 | |
|     ]])
 | |
|   end)
 | |
| 
 | |
|   it('output to pipe: has("ttyin")==1 has("ttyout")==0', function()
 | |
|     clear({ env = { NVIM_LOG_FILE = testlog } })
 | |
|     if is_os('win') then
 | |
|       command([[set shellcmdflag=/s\ /c shellxquote=\"]])
 | |
|     end
 | |
|     os.remove('Xtest_startup_ttyout')
 | |
|     finally(function()
 | |
|       os.remove('Xtest_startup_ttyout')
 | |
|     end)
 | |
|     -- Running in :terminal
 | |
|     fn.termopen(
 | |
|       (
 | |
|         [["%s" -u NONE -i NONE --cmd "%s"]]
 | |
|         .. [[ -c "call writefile([has('ttyin'), has('ttyout')], 'Xtest_startup_ttyout')"]]
 | |
|         .. [[ -c q | cat -v]]
 | |
|       ):format(nvim_prog, nvim_set),
 | |
|       {
 | |
|         env = {
 | |
|           VIMRUNTIME = os.getenv('VIMRUNTIME'),
 | |
|         },
 | |
|       }
 | |
|     )
 | |
|     retry(nil, 3000, function()
 | |
|       sleep(1)
 | |
|       eq(
 | |
|         '1\n0\n', -- stdin is a TTY, stdout is a pipe
 | |
|         read_file('Xtest_startup_ttyout')
 | |
|       )
 | |
|     end)
 | |
|     if is_os('win') then
 | |
|       assert_log('stream write failed. RPC canceled; closing channel', testlog)
 | |
|     end
 | |
|   end)
 | |
| 
 | |
|   it('input from pipe: has("ttyin")==0 has("ttyout")==1', function()
 | |
|     clear({ env = { NVIM_LOG_FILE = testlog } })
 | |
|     if is_os('win') then
 | |
|       command([[set shellcmdflag=/s\ /c shellxquote=\"]])
 | |
|     end
 | |
|     os.remove('Xtest_startup_ttyout')
 | |
|     finally(function()
 | |
|       os.remove('Xtest_startup_ttyout')
 | |
|     end)
 | |
|     -- Running in :terminal
 | |
|     fn.termopen(
 | |
|       (
 | |
|         [[echo foo | ]] -- Input from a pipe.
 | |
|         .. [["%s" -u NONE -i NONE --cmd "%s"]]
 | |
|         .. [[ -c "call writefile([has('ttyin'), has('ttyout')], 'Xtest_startup_ttyout')"]]
 | |
|         .. [[ -c q -- -]]
 | |
|       ):format(nvim_prog, nvim_set),
 | |
|       {
 | |
|         env = {
 | |
|           VIMRUNTIME = os.getenv('VIMRUNTIME'),
 | |
|         },
 | |
|       }
 | |
|     )
 | |
|     retry(nil, 3000, function()
 | |
|       sleep(1)
 | |
|       eq(
 | |
|         '0\n1\n', -- stdin is a pipe, stdout is a TTY
 | |
|         read_file('Xtest_startup_ttyout')
 | |
|       )
 | |
|     end)
 | |
|     if is_os('win') then
 | |
|       assert_log('stream write failed. RPC canceled; closing channel', testlog)
 | |
|     end
 | |
|   end)
 | |
| 
 | |
|   it('input from pipe (implicit) #7679', function()
 | |
|     clear({ env = { NVIM_LOG_FILE = testlog } })
 | |
|     local screen = Screen.new(25, 4)
 | |
|     screen:attach()
 | |
|     screen._default_attr_ids = nil
 | |
|     if is_os('win') then
 | |
|       command([[set shellcmdflag=/s\ /c shellxquote=\"]])
 | |
|     end
 | |
|     -- Running in :terminal
 | |
|     fn.termopen(
 | |
|       (
 | |
|         [[echo foo | ]]
 | |
|         .. [["%s" -u NONE -i NONE --cmd "%s"]]
 | |
|         .. [[ -c "echo has('ttyin') has('ttyout')"]]
 | |
|       ):format(nvim_prog, nvim_set),
 | |
|       {
 | |
|         env = {
 | |
|           VIMRUNTIME = os.getenv('VIMRUNTIME'),
 | |
|         },
 | |
|       }
 | |
|     )
 | |
|     screen:expect([[
 | |
|       ^foo                      |
 | |
|       ~                        |
 | |
|       0 1                      |
 | |
|                                |
 | |
|     ]])
 | |
|     if not is_os('win') then
 | |
|       assert_log('Failed to get flags on descriptor 3: Bad file descriptor', testlog, 100)
 | |
|     end
 | |
|   end)
 | |
| 
 | |
|   it('input from pipe + file args #7679', function()
 | |
|     eq(
 | |
|       'ohyeah\r\n0 0 bufs=3',
 | |
|       fn.system({
 | |
|         nvim_prog,
 | |
|         '-n',
 | |
|         '-u',
 | |
|         'NONE',
 | |
|         '-i',
 | |
|         'NONE',
 | |
|         '--headless',
 | |
|         '+.print',
 | |
|         "+echo has('ttyin') has('ttyout') 'bufs='.bufnr('$')",
 | |
|         '+qall!',
 | |
|         '-',
 | |
|         'test/functional/fixtures/tty-test.c',
 | |
|         'test/functional/fixtures/shell-test.c',
 | |
|       }, { 'ohyeah', '' })
 | |
|     )
 | |
|   end)
 | |
| 
 | |
|   it('if stdin is empty: selects buffer 2, deletes buffer 1 #8561', function()
 | |
|     eq(
 | |
|       '\r\n  2 %a   "file1"                        line 0\r\n  3      "file2"                        line 0',
 | |
|       fn.system({
 | |
|         nvim_prog,
 | |
|         '-n',
 | |
|         '-u',
 | |
|         'NONE',
 | |
|         '-i',
 | |
|         'NONE',
 | |
|         '--headless',
 | |
|         '+ls!',
 | |
|         '+qall!',
 | |
|         '-',
 | |
|         'file1',
 | |
|         'file2',
 | |
|       }, { '' })
 | |
|     )
 | |
|   end)
 | |
| 
 | |
|   it('stdin with -es/-Es #7679', function()
 | |
|     local input = { 'append', 'line1', 'line2', '.', '%print', '' }
 | |
|     local inputstr = table.concat(input, '\n')
 | |
| 
 | |
|     --
 | |
|     -- -Es: read stdin as text
 | |
|     --
 | |
|     eq(
 | |
|       'partylikeits1999\n',
 | |
|       fn.system({
 | |
|         nvim_prog,
 | |
|         '-n',
 | |
|         '-u',
 | |
|         'NONE',
 | |
|         '-i',
 | |
|         'NONE',
 | |
|         '-Es',
 | |
|         '+.print',
 | |
|         'test/functional/fixtures/tty-test.c',
 | |
|       }, { 'partylikeits1999', '' })
 | |
|     )
 | |
|     eq(inputstr, fn.system({ nvim_prog, '-i', 'NONE', '-Es', '+%print', '-' }, input))
 | |
|     -- with `-u NORC`
 | |
|     eq(
 | |
|       'thepartycontinues\n',
 | |
|       fn.system({ nvim_prog, '-n', '-u', 'NORC', '-Es', '+.print' }, { 'thepartycontinues', '' })
 | |
|     )
 | |
|     -- without `-u`
 | |
|     eq(
 | |
|       'thepartycontinues\n',
 | |
|       fn.system({ nvim_prog, '-n', '-Es', '+.print' }, { 'thepartycontinues', '' })
 | |
|     )
 | |
| 
 | |
|     --
 | |
|     -- -es: read stdin as ex-commands
 | |
|     --
 | |
|     eq(
 | |
|       '  encoding=utf-8\n',
 | |
|       fn.system({
 | |
|         nvim_prog,
 | |
|         '-n',
 | |
|         '-u',
 | |
|         'NONE',
 | |
|         '-i',
 | |
|         'NONE',
 | |
|         '-es',
 | |
|         'test/functional/fixtures/tty-test.c',
 | |
|       }, { 'set encoding', '' })
 | |
|     )
 | |
|     eq('line1\nline2\n', fn.system({ nvim_prog, '-i', 'NONE', '-es', '-' }, input))
 | |
|     -- with `-u NORC`
 | |
|     eq(
 | |
|       '  encoding=utf-8\n',
 | |
|       fn.system({ nvim_prog, '-n', '-u', 'NORC', '-es' }, { 'set encoding', '' })
 | |
|     )
 | |
|     -- without `-u`
 | |
|     eq('  encoding=utf-8\n', fn.system({ nvim_prog, '-n', '-es' }, { 'set encoding', '' }))
 | |
|   end)
 | |
| 
 | |
|   it('-es/-Es disables swapfile, user config #8540', function()
 | |
|     for _, arg in ipairs({ '-es', '-Es' }) do
 | |
|       local out = fn.system({
 | |
|         nvim_prog,
 | |
|         arg,
 | |
|         '+set swapfile? updatecount? shadafile?',
 | |
|         '+put =map(getscriptinfo(), {-> v:val.name})',
 | |
|         '+%print',
 | |
|       })
 | |
|       local line1 = string.match(out, '^.-\n')
 | |
|       -- updatecount=0 means swapfile was disabled.
 | |
|       eq('  swapfile  updatecount=0  shadafile=\n', line1)
 | |
|       -- Standard plugins were loaded, but not user config.
 | |
|       ok(string.find(out, 'man.lua') ~= nil)
 | |
|       ok(string.find(out, 'init.vim') == nil)
 | |
|     end
 | |
|   end)
 | |
| 
 | |
|   it('fails on --embed with -es/-Es/-l', function()
 | |
|     matches(
 | |
|       'nvim[.exe]*: %-%-embed conflicts with %-es/%-Es/%-l',
 | |
|       fn.system({ nvim_prog, '--embed', '-es' })
 | |
|     )
 | |
|     matches(
 | |
|       'nvim[.exe]*: %-%-embed conflicts with %-es/%-Es/%-l',
 | |
|       fn.system({ nvim_prog, '--embed', '-Es' })
 | |
|     )
 | |
|     matches(
 | |
|       'nvim[.exe]*: %-%-embed conflicts with %-es/%-Es/%-l',
 | |
|       fn.system({ nvim_prog, '--embed', '-l', 'foo.lua' })
 | |
|     )
 | |
|   end)
 | |
| 
 | |
|   it('ENTER dismisses early message #7967', function()
 | |
|     local screen
 | |
|     screen = Screen.new(60, 6)
 | |
|     screen:attach()
 | |
|     screen._default_attr_ids = nil
 | |
|     local id = fn.termopen({
 | |
|       nvim_prog,
 | |
|       '-u',
 | |
|       'NONE',
 | |
|       '-i',
 | |
|       'NONE',
 | |
|       '--cmd',
 | |
|       'set noruler',
 | |
|       '--cmd',
 | |
|       'let g:foo = g:bar',
 | |
|     }, {
 | |
|       env = {
 | |
|         VIMRUNTIME = os.getenv('VIMRUNTIME'),
 | |
|       },
 | |
|     })
 | |
|     screen:expect([[
 | |
|       ^                                                            |
 | |
|                                                                   |
 | |
|       Error detected while processing pre-vimrc command line:     |
 | |
|       E121: Undefined variable: g:bar                             |
 | |
|       Press ENTER or type command to continue                     |
 | |
|                                                                   |
 | |
|     ]])
 | |
|     fn.chansend(id, '\n')
 | |
|     screen:expect([[
 | |
|       ^                                                            |
 | |
|       ~                                                           |*2
 | |
|       [No Name]                                                   |
 | |
|                                                                   |*2
 | |
|     ]])
 | |
|   end)
 | |
| 
 | |
|   it('-r works without --headless in PTY #23294', function()
 | |
|     exec([[
 | |
|       func Normalize(data) abort
 | |
|         " Windows: remove ^M and term escape sequences
 | |
|         return map(a:data, 'substitute(substitute(v:val, "\r", "", "g"), "\x1b\\%(\\]\\d\\+;.\\{-}\x07\\|\\[.\\{-}[\x40-\x7E]\\)", "", "g")')
 | |
|       endfunc
 | |
|       func OnOutput(id, data, event) dict
 | |
|         let g:stdout = Normalize(a:data)
 | |
|       endfunc
 | |
|       call jobstart([v:progpath, '-u', 'NONE', '-i', 'NONE', '-r'], {
 | |
|       \ 'pty': v:true,
 | |
|       \ 'stdout_buffered': v:true,
 | |
|       \ 'on_stdout': function('OnOutput'),
 | |
|       \ })
 | |
|     ]])
 | |
|     retry(nil, nil, function()
 | |
|       eq('Swap files found:', eval('g:stdout[0]'))
 | |
|     end)
 | |
|   end)
 | |
| 
 | |
|   it('fixed hang issue with --headless (#11386)', function()
 | |
|     local expected = ''
 | |
|     local period = 100
 | |
|     for i = 1, period - 1 do
 | |
|       expected = expected .. i .. '\r\n'
 | |
|     end
 | |
|     expected = expected .. period
 | |
|     eq(
 | |
|       expected,
 | |
|       -- FIXME(codehex): We should really set a timeout for the system function.
 | |
|       -- If this test fails, there will be a waiting input state.
 | |
|       fn.system({
 | |
|         nvim_prog,
 | |
|         '-u',
 | |
|         'NONE',
 | |
|         '-c',
 | |
|         'for i in range(1, 100) | echo i | endfor | quit',
 | |
|         '--headless',
 | |
|       })
 | |
|     )
 | |
|   end)
 | |
| 
 | |
|   it('get command line arguments from v:argv', function()
 | |
|     local out = fn.system({
 | |
|       nvim_prog,
 | |
|       '-u',
 | |
|       'NONE',
 | |
|       '-i',
 | |
|       'NONE',
 | |
|       '--headless',
 | |
|       '--cmd',
 | |
|       nvim_set,
 | |
|       '-c',
 | |
|       [[echo v:argv[-1:] len(v:argv) > 1]],
 | |
|       '+q',
 | |
|     })
 | |
|     eq("['+q'] 1", out)
 | |
|   end)
 | |
| end)
 | |
| 
 | |
| describe('startup', function()
 | |
|   it('-e/-E interactive #7679', function()
 | |
|     clear('-e')
 | |
|     local screen = Screen.new(25, 3)
 | |
|     screen:attach()
 | |
|     feed("put ='from -e'<CR>")
 | |
|     screen:expect([[
 | |
|       :put ='from -e'          |
 | |
|       from -e                  |
 | |
|       :^                        |
 | |
|     ]])
 | |
| 
 | |
|     clear('-E')
 | |
|     screen = Screen.new(25, 3)
 | |
|     screen:attach()
 | |
|     feed("put ='from -E'<CR>")
 | |
|     screen:expect([[
 | |
|       :put ='from -E'          |
 | |
|       from -E                  |
 | |
|       :^                        |
 | |
|     ]])
 | |
|   end)
 | |
| 
 | |
|   it('-e sets ex mode', function()
 | |
|     local screen = Screen.new(25, 3)
 | |
|     clear('-e')
 | |
|     screen:attach()
 | |
|     -- Verify we set the proper mode both before and after :vi.
 | |
|     feed('put =mode(1)<CR>vi<CR>:put =mode(1)<CR>')
 | |
|     screen:expect([[
 | |
|       cv                       |
 | |
|       ^n                        |
 | |
|       :put =mode(1)            |
 | |
|     ]])
 | |
| 
 | |
|     eq('cv\n', fn.system({ nvim_prog, '-n', '-es' }, { 'put =mode(1)', 'print', '' }))
 | |
|   end)
 | |
| 
 | |
|   it('-d does not diff non-arglist windows #13720 #21289', function()
 | |
|     write_file(
 | |
|       'Xdiff.vim',
 | |
|       [[
 | |
|       let bufnr = nvim_create_buf(0, 1)
 | |
|       let config = {
 | |
|             \   'relative': 'editor',
 | |
|             \   'focusable': v:false,
 | |
|             \   'width': 1,
 | |
|             \   'height': 1,
 | |
|             \   'row': 3,
 | |
|             \   'col': 3
 | |
|             \ }
 | |
|       autocmd WinEnter * call nvim_open_win(bufnr, v:false, config)]]
 | |
|     )
 | |
|     finally(function()
 | |
|       os.remove('Xdiff.vim')
 | |
|     end)
 | |
|     clear { args = { '-u', 'Xdiff.vim', '-d', 'Xdiff.vim', 'Xdiff.vim' } }
 | |
|     eq(true, api.nvim_get_option_value('diff', { win = fn.win_getid(1) }))
 | |
|     eq(true, api.nvim_get_option_value('diff', { win = fn.win_getid(2) }))
 | |
|     local float_win = fn.win_getid(3)
 | |
|     eq('editor', api.nvim_win_get_config(float_win).relative)
 | |
|     eq(false, api.nvim_get_option_value('diff', { win = float_win }))
 | |
|   end)
 | |
| 
 | |
|   it('does not crash if --embed is given twice', function()
 | |
|     clear { args = { '--embed' } }
 | |
|     assert_alive()
 | |
|   end)
 | |
| 
 | |
|   it('does not crash when expanding cdpath during early_init', function()
 | |
|     clear { env = { CDPATH = '~doesnotexist' } }
 | |
|     assert_alive()
 | |
|     eq(',~doesnotexist', eval('&cdpath'))
 | |
|   end)
 | |
| 
 | |
|   it("sets 'shortmess' when loading other tabs", function()
 | |
|     clear({ args = { '-p', 'a', 'b', 'c' } })
 | |
|     local screen = Screen.new(25, 4)
 | |
|     screen:attach()
 | |
|     screen:expect({
 | |
|       grid = [[
 | |
|         {1: a }{2: b  c }{3:               }{2:X}|
 | |
|         ^                         |
 | |
|         {4:~                        }|
 | |
|                                  |
 | |
|           ]],
 | |
|       attr_ids = {
 | |
|         [1] = { bold = true },
 | |
|         [2] = { background = Screen.colors.LightGrey, underline = true },
 | |
|         [3] = { reverse = true },
 | |
|         [4] = { bold = true, foreground = Screen.colors.Blue1 },
 | |
|       },
 | |
|     })
 | |
|   end)
 | |
| end)
 | |
| 
 | |
| describe('startup', function()
 | |
|   local function pack_clear(cmd)
 | |
|     -- add packages after config dir in rtp but before config/after
 | |
|     clear {
 | |
|       args = {
 | |
|         '--cmd',
 | |
|         'set packpath=test/functional/fixtures',
 | |
|         '--cmd',
 | |
|         'let paths=split(&rtp, ",")',
 | |
|         '--cmd',
 | |
|         'let &rtp = paths[0]..",test/functional/fixtures,test/functional/fixtures/middle,"..join(paths[1:],",")',
 | |
|         '--cmd',
 | |
|         cmd,
 | |
|       },
 | |
|       env = { XDG_CONFIG_HOME = 'test/functional/fixtures/' },
 | |
|       args_rm = { 'runtimepath' },
 | |
|     }
 | |
|   end
 | |
| 
 | |
|   it('handles &packpath during startup', function()
 | |
|     pack_clear [[
 | |
|       let g:x = bar#test()
 | |
|       let g:y = leftpad#pad("heyya")
 | |
|     ]]
 | |
|     eq(-3, eval 'g:x')
 | |
|     eq('  heyya', eval 'g:y')
 | |
| 
 | |
|     pack_clear [[ lua _G.y = require'bar'.doit() _G.z = require'leftpad''howdy' ]]
 | |
|     eq({ 9003, '\thowdy' }, exec_lua [[ return { _G.y, _G.z } ]])
 | |
|   end)
 | |
| 
 | |
|   it('handles require from &packpath in an async handler', function()
 | |
|     -- NO! you cannot just speed things up by calling async functions during startup!
 | |
|     -- It doesn't make anything actually faster! NOOOO!
 | |
|     pack_clear [[ lua require'async_leftpad'('brrrr', 'async_res') ]]
 | |
| 
 | |
|     -- haha, async leftpad go brrrrr
 | |
|     eq('\tbrrrr', exec_lua [[ return _G.async_res ]])
 | |
|   end)
 | |
| 
 | |
|   it('handles :packadd during startup', function()
 | |
|     -- control group: opt/bonus is not available by default
 | |
|     pack_clear [[
 | |
|       try
 | |
|         let g:x = bonus#secret()
 | |
|       catch
 | |
|         let g:err = v:exception
 | |
|       endtry
 | |
|     ]]
 | |
|     eq('Vim(let):E117: Unknown function: bonus#secret', eval 'g:err')
 | |
| 
 | |
|     pack_clear [[ lua _G.test = {pcall(function() require'bonus'.launch() end)} ]]
 | |
|     eq(
 | |
|       { false, [[[string ":lua"]:1: module 'bonus' not found:]] },
 | |
|       exec_lua [[ _G.test[2] = string.gsub(_G.test[2], '[\r\n].*', '') return _G.test ]]
 | |
|     )
 | |
| 
 | |
|     -- ok, time to launch the nukes:
 | |
|     pack_clear [[ packadd! bonus | let g:x = bonus#secret() ]]
 | |
|     eq('halloj', eval 'g:x')
 | |
| 
 | |
|     pack_clear [[ packadd! bonus | lua _G.y = require'bonus'.launch() ]]
 | |
|     eq('CPE 1704 TKS', exec_lua [[ return _G.y ]])
 | |
|   end)
 | |
| 
 | |
|   it('handles the correct order with start packages and after/', function()
 | |
|     pack_clear [[ lua _G.test_loadorder = {} vim.cmd "runtime! filen.lua" ]]
 | |
|     eq(
 | |
|       { 'ordinary', 'FANCY', 'mittel', 'FANCY after', 'ordinary after' },
 | |
|       exec_lua [[ return _G.test_loadorder ]]
 | |
|     )
 | |
|   end)
 | |
| 
 | |
|   it('handles the correct order with start packages and after/ after startup', function()
 | |
|     pack_clear [[ lua _G.test_loadorder = {} ]]
 | |
|     command [[ runtime! filen.lua ]]
 | |
|     eq(
 | |
|       { 'ordinary', 'FANCY', 'mittel', 'FANCY after', 'ordinary after' },
 | |
|       exec_lua [[ return _G.test_loadorder ]]
 | |
|     )
 | |
|   end)
 | |
| 
 | |
|   it('handles the correct order with globpath(&rtp, ...)', function()
 | |
|     pack_clear [[ set loadplugins | lua _G.test_loadorder = {} ]]
 | |
|     command [[
 | |
|       for x in globpath(&rtp, "filen.lua",1,1)
 | |
|         call v:lua.dofile(x)
 | |
|       endfor
 | |
|     ]]
 | |
|     eq(
 | |
|       { 'ordinary', 'FANCY', 'mittel', 'FANCY after', 'ordinary after' },
 | |
|       exec_lua [[ return _G.test_loadorder ]]
 | |
|     )
 | |
| 
 | |
|     local rtp = api.nvim_get_option_value('rtp', {})
 | |
|     ok(
 | |
|       startswith(
 | |
|         rtp,
 | |
|         'test/functional/fixtures/nvim,test/functional/fixtures/pack/*/start/*,test/functional/fixtures/start/*,test/functional/fixtures,test/functional/fixtures/middle,'
 | |
|       ),
 | |
|       'startswith(…)',
 | |
|       'rtp=' .. rtp
 | |
|     )
 | |
|   end)
 | |
| 
 | |
|   it('handles the correct order with opt packages and after/', function()
 | |
|     pack_clear [[ lua _G.test_loadorder = {} vim.cmd "packadd! superspecial\nruntime! filen.lua" ]]
 | |
|     eq({
 | |
|       'ordinary',
 | |
|       'SuperSpecial',
 | |
|       'FANCY',
 | |
|       'mittel',
 | |
|       'FANCY after',
 | |
|       'SuperSpecial after',
 | |
|       'ordinary after',
 | |
|     }, exec_lua [[ return _G.test_loadorder ]])
 | |
|   end)
 | |
| 
 | |
|   it('handles the correct order with opt packages and after/ after startup', function()
 | |
|     pack_clear [[ lua _G.test_loadorder = {} ]]
 | |
|     command [[
 | |
|       packadd! superspecial
 | |
|       runtime! filen.lua
 | |
|     ]]
 | |
|     eq({
 | |
|       'ordinary',
 | |
|       'SuperSpecial',
 | |
|       'FANCY',
 | |
|       'mittel',
 | |
|       'FANCY after',
 | |
|       'SuperSpecial after',
 | |
|       'ordinary after',
 | |
|     }, exec_lua [[ return _G.test_loadorder ]])
 | |
|   end)
 | |
| 
 | |
|   it('handles the correct order with opt packages and globpath(&rtp, ...)', function()
 | |
|     pack_clear [[ set loadplugins | lua _G.test_loadorder = {} ]]
 | |
|     command [[
 | |
|       packadd! superspecial
 | |
|       for x in globpath(&rtp, "filen.lua",1,1)
 | |
|         call v:lua.dofile(x)
 | |
|       endfor
 | |
|     ]]
 | |
|     eq({
 | |
|       'ordinary',
 | |
|       'SuperSpecial',
 | |
|       'FANCY',
 | |
|       'mittel',
 | |
|       'SuperSpecial after',
 | |
|       'FANCY after',
 | |
|       'ordinary after',
 | |
|     }, exec_lua [[ return _G.test_loadorder ]])
 | |
|   end)
 | |
| 
 | |
|   it('handles the correct order with a package that changes packpath', function()
 | |
|     pack_clear [[ lua _G.test_loadorder = {} vim.cmd "packadd! funky\nruntime! filen.lua" ]]
 | |
|     eq(
 | |
|       { 'ordinary', 'funky!', 'FANCY', 'mittel', 'FANCY after', 'ordinary after' },
 | |
|       exec_lua [[ return _G.test_loadorder ]]
 | |
|     )
 | |
|     eq({ 'ordinary', 'funky!', 'mittel', 'ordinary after' }, exec_lua [[ return _G.nested_order ]])
 | |
|   end)
 | |
| 
 | |
|   it('handles the correct order when prepending packpath', function()
 | |
|     clear {
 | |
|       args = {
 | |
|         '--cmd',
 | |
|         'set packpath^=test/functional/fixtures',
 | |
|         '--cmd',
 | |
|         [[ lua _G.test_loadorder = {} vim.cmd "runtime! filen.lua" ]],
 | |
|       },
 | |
|       env = { XDG_CONFIG_HOME = 'test/functional/fixtures/' },
 | |
|     }
 | |
|     eq(
 | |
|       { 'ordinary', 'FANCY', 'FANCY after', 'ordinary after' },
 | |
|       exec_lua [[ return _G.test_loadorder ]]
 | |
|     )
 | |
|   end)
 | |
| 
 | |
|   it('window widths are correct when modelines set &columns with tabpages', function()
 | |
|     write_file('Xtab1.noft', 'vim: columns=81')
 | |
|     write_file('Xtab2.noft', 'vim: columns=81')
 | |
|     finally(function()
 | |
|       os.remove('Xtab1.noft')
 | |
|       os.remove('Xtab2.noft')
 | |
|     end)
 | |
|     clear({ args = { '-p', 'Xtab1.noft', 'Xtab2.noft' } })
 | |
|     eq(81, api.nvim_win_get_width(0))
 | |
|     command('tabnext')
 | |
|     eq(81, api.nvim_win_get_width(0))
 | |
|   end)
 | |
| end)
 | |
| 
 | |
| describe('sysinit', function()
 | |
|   local xdgdir = 'Xxdg'
 | |
|   local vimdir = 'Xvim'
 | |
|   local xhome = 'Xhome'
 | |
|   local pathsep = n.get_pathsep()
 | |
| 
 | |
|   before_each(function()
 | |
|     rmdir(xdgdir)
 | |
|     rmdir(vimdir)
 | |
|     rmdir(xhome)
 | |
| 
 | |
|     mkdir(xdgdir)
 | |
|     mkdir(xdgdir .. pathsep .. 'nvim')
 | |
|     write_file(
 | |
|       table.concat({ xdgdir, 'nvim', 'sysinit.vim' }, pathsep),
 | |
|       [[
 | |
|       let g:loaded = get(g:, "loaded", 0) + 1
 | |
|       let g:xdg = 1
 | |
|     ]]
 | |
|     )
 | |
| 
 | |
|     mkdir(vimdir)
 | |
|     write_file(
 | |
|       table.concat({ vimdir, 'sysinit.vim' }, pathsep),
 | |
|       [[
 | |
|       let g:loaded = get(g:, "loaded", 0) + 1
 | |
|       let g:vim = 1
 | |
|     ]]
 | |
|     )
 | |
| 
 | |
|     mkdir(xhome)
 | |
|   end)
 | |
|   after_each(function()
 | |
|     rmdir(xdgdir)
 | |
|     rmdir(vimdir)
 | |
|     rmdir(xhome)
 | |
|   end)
 | |
| 
 | |
|   it('prefers XDG_CONFIG_DIRS over VIM', function()
 | |
|     clear {
 | |
|       args = { '--cmd', 'set nomore undodir=. directory=. belloff=' },
 | |
|       args_rm = { '-u', '--cmd' },
 | |
|       env = { HOME = xhome, XDG_CONFIG_DIRS = xdgdir, VIM = vimdir },
 | |
|     }
 | |
|     eq(
 | |
|       'loaded 1 xdg 1 vim 0',
 | |
|       eval('printf("loaded %d xdg %d vim %d", g:loaded, get(g:, "xdg", 0), get(g:, "vim", 0))')
 | |
|     )
 | |
|   end)
 | |
| 
 | |
|   it('uses VIM if XDG_CONFIG_DIRS unset', function()
 | |
|     clear {
 | |
|       args = { '--cmd', 'set nomore undodir=. directory=. belloff=' },
 | |
|       args_rm = { '-u', '--cmd' },
 | |
|       env = { HOME = xhome, XDG_CONFIG_DIRS = '', VIM = vimdir },
 | |
|     }
 | |
|     eq(
 | |
|       'loaded 1 xdg 0 vim 1',
 | |
|       eval('printf("loaded %d xdg %d vim %d", g:loaded, get(g:, "xdg", 0), get(g:, "vim", 0))')
 | |
|     )
 | |
|   end)
 | |
| end)
 | |
| 
 | |
| describe('user config init', function()
 | |
|   local xhome = 'Xhome'
 | |
|   local pathsep = n.get_pathsep()
 | |
|   local xconfig = xhome .. pathsep .. 'Xconfig'
 | |
|   local xdata = xhome .. pathsep .. 'Xdata'
 | |
|   local init_lua_path = table.concat({ xconfig, 'nvim', 'init.lua' }, pathsep)
 | |
|   local xenv = { XDG_CONFIG_HOME = xconfig, XDG_DATA_HOME = xdata }
 | |
| 
 | |
|   before_each(function()
 | |
|     rmdir(xhome)
 | |
| 
 | |
|     mkdir_p(xconfig .. pathsep .. 'nvim')
 | |
|     mkdir_p(xdata)
 | |
| 
 | |
|     write_file(
 | |
|       init_lua_path,
 | |
|       [[
 | |
|       vim.g.lua_rc = 1
 | |
|     ]]
 | |
|     )
 | |
|   end)
 | |
| 
 | |
|   after_each(function()
 | |
|     rmdir(xhome)
 | |
|   end)
 | |
| 
 | |
|   it('loads init.lua from XDG config home by default', function()
 | |
|     clear { args_rm = { '-u' }, env = xenv }
 | |
| 
 | |
|     eq(1, eval('g:lua_rc'))
 | |
|     eq(fn.fnamemodify(init_lua_path, ':p'), eval('$MYVIMRC'))
 | |
|   end)
 | |
| 
 | |
|   describe('loads existing', function()
 | |
|     local exrc_path = '.exrc'
 | |
|     local xstate = 'Xstate'
 | |
|     local xstateenv = { XDG_CONFIG_HOME = xconfig, XDG_DATA_HOME = xdata, XDG_STATE_HOME = xstate }
 | |
| 
 | |
|     local function setup_exrc_file(filename)
 | |
|       exrc_path = filename
 | |
| 
 | |
|       if string.find(exrc_path, '%.lua$') then
 | |
|         write_file(
 | |
|           exrc_path,
 | |
|           string.format(
 | |
|             [[
 | |
|           vim.g.exrc_file = "%s"
 | |
|         ]],
 | |
|             exrc_path
 | |
|           )
 | |
|         )
 | |
|       else
 | |
|         write_file(
 | |
|           exrc_path,
 | |
|           string.format(
 | |
|             [[
 | |
|           let g:exrc_file = "%s"
 | |
|         ]],
 | |
|             exrc_path
 | |
|           )
 | |
|         )
 | |
|       end
 | |
|     end
 | |
| 
 | |
|     before_each(function()
 | |
|       write_file(
 | |
|         init_lua_path,
 | |
|         [[
 | |
|         vim.o.exrc = true
 | |
|         vim.g.exrc_file = '---'
 | |
|       ]]
 | |
|       )
 | |
|       mkdir_p(xstate .. pathsep .. (is_os('win') and 'nvim-data' or 'nvim'))
 | |
|     end)
 | |
| 
 | |
|     after_each(function()
 | |
|       os.remove(exrc_path)
 | |
|       rmdir(xstate)
 | |
|     end)
 | |
| 
 | |
|     for _, filename in ipairs({ '.exrc', '.nvimrc', '.nvim.lua' }) do
 | |
|       it(filename .. ' in cwd', function()
 | |
|         setup_exrc_file(filename)
 | |
| 
 | |
|         clear { args_rm = { '-u' }, env = xstateenv }
 | |
|         -- The 'exrc' file is not trusted, and the prompt is skipped because there is no UI.
 | |
|         eq('---', eval('g:exrc_file'))
 | |
| 
 | |
|         local screen = Screen.new(50, 8)
 | |
|         screen:attach()
 | |
|         screen._default_attr_ids = nil
 | |
|         fn.termopen({ nvim_prog }, {
 | |
|           env = {
 | |
|             VIMRUNTIME = os.getenv('VIMRUNTIME'),
 | |
|           },
 | |
|         })
 | |
|         screen:expect({ any = pesc('[i]gnore, (v)iew, (d)eny, (a)llow:') })
 | |
|         -- `i` to enter Terminal mode, `a` to allow
 | |
|         feed('ia')
 | |
|         screen:expect([[
 | |
|                                                             |
 | |
|           ~                                                 |*4
 | |
|           [No Name]                       0,0-1          All|
 | |
|                                                             |
 | |
|           -- TERMINAL --                                    |
 | |
|         ]])
 | |
|         feed(':echo g:exrc_file<CR>')
 | |
|         screen:expect(string.format(
 | |
|           [[
 | |
|                                                             |
 | |
|           ~                                                 |*4
 | |
|           [No Name]                       0,0-1          All|
 | |
|           %s%s|
 | |
|           -- TERMINAL --                                    |
 | |
|         ]],
 | |
|           filename,
 | |
|           string.rep(' ', 50 - #filename)
 | |
|         ))
 | |
| 
 | |
|         clear { args_rm = { '-u' }, env = xstateenv }
 | |
|         -- The 'exrc' file is now trusted.
 | |
|         eq(filename, eval('g:exrc_file'))
 | |
|       end)
 | |
|     end
 | |
|   end)
 | |
| 
 | |
|   describe('with explicitly provided config', function()
 | |
|     local custom_lua_path = table.concat({ xhome, 'custom.lua' }, pathsep)
 | |
|     before_each(function()
 | |
|       write_file(
 | |
|         custom_lua_path,
 | |
|         [[
 | |
|       vim.g.custom_lua_rc = 1
 | |
|       ]]
 | |
|       )
 | |
|     end)
 | |
| 
 | |
|     it('loads custom lua config and does not set $MYVIMRC', function()
 | |
|       clear { args = { '-u', custom_lua_path }, env = xenv }
 | |
|       eq(1, eval('g:custom_lua_rc'))
 | |
|       eq('', eval('$MYVIMRC'))
 | |
|     end)
 | |
|   end)
 | |
| 
 | |
|   describe('VIMRC also exists', function()
 | |
|     before_each(function()
 | |
|       write_file(
 | |
|         table.concat({ xconfig, 'nvim', 'init.vim' }, pathsep),
 | |
|         [[
 | |
|       let g:vim_rc = 1
 | |
|       ]]
 | |
|       )
 | |
|     end)
 | |
| 
 | |
|     it('loads default lua config, but shows an error', function()
 | |
|       clear { args_rm = { '-u' }, env = xenv }
 | |
|       feed('<cr><c-c>') -- Dismiss "Conflicting config …" message.
 | |
|       eq(1, eval('g:lua_rc'))
 | |
|       matches('^E5422: Conflicting configs', exec_capture('messages'))
 | |
|     end)
 | |
|   end)
 | |
| end)
 | |
| 
 | |
| describe('runtime:', function()
 | |
|   local xhome = 'Xhome'
 | |
|   local pathsep = n.get_pathsep()
 | |
|   local xconfig = xhome .. pathsep .. 'Xconfig'
 | |
|   local xdata = xhome .. pathsep .. 'Xdata'
 | |
|   local xenv = { XDG_CONFIG_HOME = xconfig, XDG_DATA_HOME = xdata }
 | |
| 
 | |
|   setup(function()
 | |
|     rmdir(xhome)
 | |
|     mkdir_p(xconfig .. pathsep .. 'nvim')
 | |
|     mkdir_p(xdata)
 | |
|   end)
 | |
| 
 | |
|   teardown(function()
 | |
|     rmdir(xhome)
 | |
|   end)
 | |
| 
 | |
|   it('loads plugin/*.lua from XDG config home', function()
 | |
|     local plugin_folder_path = table.concat({ xconfig, 'nvim', 'plugin' }, pathsep)
 | |
|     local plugin_file_path = table.concat({ plugin_folder_path, 'plugin.lua' }, pathsep)
 | |
|     mkdir_p(plugin_folder_path)
 | |
|     finally(function()
 | |
|       rmdir(plugin_folder_path)
 | |
|     end)
 | |
|     write_file(plugin_file_path, [[ vim.g.lua_plugin = 1 ]])
 | |
| 
 | |
|     clear { args_rm = { '-u' }, env = xenv }
 | |
| 
 | |
|     eq(1, eval('g:lua_plugin'))
 | |
|   end)
 | |
| 
 | |
|   it('loads plugin/*.lua from start packages', function()
 | |
|     local plugin_path =
 | |
|       table.concat({ xconfig, 'nvim', 'pack', 'category', 'start', 'test_plugin' }, pathsep)
 | |
|     local plugin_folder_path = table.concat({ plugin_path, 'plugin' }, pathsep)
 | |
|     local plugin_file_path = table.concat({ plugin_folder_path, 'plugin.lua' }, pathsep)
 | |
|     local profiler_file = 'test_startuptime.log'
 | |
|     mkdir_p(plugin_folder_path)
 | |
|     finally(function()
 | |
|       os.remove(profiler_file)
 | |
|       rmdir(plugin_path)
 | |
|     end)
 | |
| 
 | |
|     write_file(plugin_file_path, [[vim.g.lua_plugin = 2]])
 | |
| 
 | |
|     clear { args_rm = { '-u' }, args = { '--startuptime', profiler_file }, env = xenv }
 | |
| 
 | |
|     eq(2, eval('g:lua_plugin'))
 | |
|     -- Check if plugin_file_path is listed in getscriptinfo()
 | |
|     local scripts = tbl_map(function(s)
 | |
|       return s.name
 | |
|     end, fn.getscriptinfo())
 | |
|     ok(#tbl_filter(function(s)
 | |
|       return endswith(s, plugin_file_path)
 | |
|     end, scripts) > 0)
 | |
| 
 | |
|     -- Check if plugin_file_path is listed in startup profile
 | |
|     local profile_reader = io.open(profiler_file, 'r')
 | |
|     local profile_log = profile_reader:read('*a')
 | |
|     profile_reader:close()
 | |
|     ok(profile_log:find(plugin_file_path) ~= nil)
 | |
|   end)
 | |
| 
 | |
|   it('loads plugin/*.lua from site packages', function()
 | |
|     local nvimdata = is_os('win') and 'nvim-data' or 'nvim'
 | |
|     local plugin_path =
 | |
|       table.concat({ xdata, nvimdata, 'site', 'pack', 'xa', 'start', 'yb' }, pathsep)
 | |
|     local plugin_folder_path = table.concat({ plugin_path, 'plugin' }, pathsep)
 | |
|     local plugin_after_path = table.concat({ plugin_path, 'after', 'plugin' }, pathsep)
 | |
|     local plugin_file_path = table.concat({ plugin_folder_path, 'plugin.lua' }, pathsep)
 | |
|     local plugin_after_file_path = table.concat({ plugin_after_path, 'helloo.lua' }, pathsep)
 | |
|     mkdir_p(plugin_folder_path)
 | |
|     mkdir_p(plugin_after_path)
 | |
|     finally(function()
 | |
|       rmdir(plugin_path)
 | |
|     end)
 | |
| 
 | |
|     write_file(plugin_file_path, [[table.insert(_G.lista, "unos")]])
 | |
|     write_file(plugin_after_file_path, [[table.insert(_G.lista, "dos")]])
 | |
| 
 | |
|     clear { args_rm = { '-u' }, args = { '--cmd', 'lua _G.lista = {}' }, env = xenv }
 | |
| 
 | |
|     eq({ 'unos', 'dos' }, exec_lua 'return _G.lista')
 | |
|   end)
 | |
| 
 | |
|   it('no crash setting &rtp in plugins with :packloadall called before #18315', function()
 | |
|     local plugin_folder_path = table.concat({ xconfig, 'nvim', 'plugin' }, pathsep)
 | |
|     mkdir_p(plugin_folder_path)
 | |
|     finally(function()
 | |
|       rmdir(plugin_folder_path)
 | |
|     end)
 | |
| 
 | |
|     write_file(
 | |
|       table.concat({ plugin_folder_path, 'plugin.vim' }, pathsep),
 | |
|       [[
 | |
|       let &runtimepath = &runtimepath
 | |
|       let g:vim_plugin = 1
 | |
|     ]]
 | |
|     )
 | |
|     write_file(
 | |
|       table.concat({ plugin_folder_path, 'plugin.lua' }, pathsep),
 | |
|       [[
 | |
|       vim.o.runtimepath = vim.o.runtimepath
 | |
|       vim.g.lua_plugin = 1
 | |
|     ]]
 | |
|     )
 | |
| 
 | |
|     clear { args_rm = { '-u' }, args = { '--cmd', 'packloadall' }, env = xenv }
 | |
| 
 | |
|     eq(1, eval('g:vim_plugin'))
 | |
|     eq(1, eval('g:lua_plugin'))
 | |
|   end)
 | |
| 
 | |
|   it("loads ftdetect/*.{vim,lua} respecting 'rtp' order", function()
 | |
|     local ftdetect_folder = table.concat({ xconfig, 'nvim', 'ftdetect' }, pathsep)
 | |
|     local after_ftdetect_folder = table.concat({ xconfig, 'nvim', 'after', 'ftdetect' }, pathsep)
 | |
|     mkdir_p(ftdetect_folder)
 | |
|     mkdir_p(after_ftdetect_folder)
 | |
|     finally(function()
 | |
|       rmdir(ftdetect_folder)
 | |
|       rmdir(after_ftdetect_folder)
 | |
|     end)
 | |
|     -- A .lua file is loaded after a .vim file if they only differ in extension.
 | |
|     -- All files in after/ftdetect/ are loaded after all files in ftdetect/.
 | |
|     write_file(table.concat({ ftdetect_folder, 'new-ft.vim' }, pathsep), [[let g:seq ..= 'A']])
 | |
|     write_file(
 | |
|       table.concat({ ftdetect_folder, 'new-ft.lua' }, pathsep),
 | |
|       [[vim.g.seq = vim.g.seq .. 'B']]
 | |
|     )
 | |
|     write_file(
 | |
|       table.concat({ after_ftdetect_folder, 'new-ft.vim' }, pathsep),
 | |
|       [[let g:seq ..= 'a']]
 | |
|     )
 | |
|     write_file(
 | |
|       table.concat({ after_ftdetect_folder, 'new-ft.lua' }, pathsep),
 | |
|       [[vim.g.seq = vim.g.seq .. 'b']]
 | |
|     )
 | |
|     clear { args_rm = { '-u' }, args = { '--cmd', 'let g:seq = ""' }, env = xenv }
 | |
|     eq('ABab', eval('g:seq'))
 | |
|   end)
 | |
| end)
 | |
| 
 | |
| describe('user session', function()
 | |
|   local xhome = 'Xhome'
 | |
|   local pathsep = n.get_pathsep()
 | |
|   local session_file = table.concat({ xhome, 'session.lua' }, pathsep)
 | |
| 
 | |
|   before_each(function()
 | |
|     rmdir(xhome)
 | |
| 
 | |
|     mkdir(xhome)
 | |
|     write_file(
 | |
|       session_file,
 | |
|       [[
 | |
|       vim.g.lua_session = 1
 | |
|     ]]
 | |
|     )
 | |
|   end)
 | |
| 
 | |
|   after_each(function()
 | |
|     rmdir(xhome)
 | |
|   end)
 | |
| 
 | |
|   it('loads session from the provided lua file', function()
 | |
|     clear { args = { '-S', session_file }, env = { HOME = xhome } }
 | |
|     eq(1, eval('g:lua_session'))
 | |
|   end)
 | |
| end)
 | |
| 
 | |
| describe('inccommand on ex mode', function()
 | |
|   it('should not preview', function()
 | |
|     clear()
 | |
|     local screen
 | |
|     screen = Screen.new(60, 10)
 | |
|     screen:attach()
 | |
|     local id = fn.termopen({
 | |
|       nvim_prog,
 | |
|       '-u',
 | |
|       'NONE',
 | |
|       '-i',
 | |
|       'NONE',
 | |
|       '-c',
 | |
|       'set termguicolors background=dark',
 | |
|       '-E',
 | |
|       'test/README.md',
 | |
|     }, {
 | |
|       env = { VIMRUNTIME = os.getenv('VIMRUNTIME') },
 | |
|     })
 | |
|     fn.chansend(id, '%s/N')
 | |
|     screen:expect {
 | |
|       grid = [[
 | |
|       {1:^                                                            }|
 | |
|       {1:                                                            }|*6
 | |
|       {1:Entering Ex mode.  Type "visual" to go to Normal mode.      }|
 | |
|       {1::%s/N                                                       }|
 | |
|                                                                   |
 | |
|     ]],
 | |
|       attr_ids = {
 | |
|         [1] = {
 | |
|           background = Screen.colors.NvimDarkGrey2,
 | |
|           foreground = Screen.colors.NvimLightGrey2,
 | |
|         },
 | |
|       },
 | |
|     }
 | |
|   end)
 | |
| end)
 |