local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') local clear = helpers.clear local command = helpers.command local ok = helpers.ok local eq = helpers.eq local matches = helpers.matches local eval = helpers.eval local feed = helpers.feed local funcs = helpers.funcs local mkdir = helpers.mkdir local nvim_prog = helpers.nvim_prog local nvim_set = helpers.nvim_set local read_file = helpers.read_file local retry = helpers.retry local rmdir = helpers.rmdir local sleep = helpers.sleep local iswin = helpers.iswin local write_file = helpers.write_file local meths = helpers.meths describe('startup', function() before_each(function() clear() os.remove('Xtest_startup_ttyout') end) after_each(function() os.remove('Xtest_startup_ttyout') end) it('pipe at both ends: has("ttyin")==0 has("ttyout")==0', function() -- system() puts a pipe at both ends. local out = funcs.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() 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() if iswin() then command([[set shellcmdflag=/s\ /c shellxquote=\"]]) end -- Running in :terminal command([[exe printf("terminal %s -u NONE -i NONE --cmd \"]] ..nvim_set..[[\"]] ..[[ -c \"echo has('ttyin') has('ttyout')\""]] ..[[, shellescape(v:progpath))]]) screen:expect([[ ^ | ~ | 1 1 | | ]]) end) it('output to pipe: has("ttyin")==1 has("ttyout")==0', function() if iswin() then command([[set shellcmdflag=/s\ /c shellxquote=\"]]) end -- Running in :terminal command([[exe printf("terminal %s -u NONE -i NONE --cmd \"]] ..nvim_set..[[\"]] ..[[ -c \"call writefile([has('ttyin'), has('ttyout')], 'Xtest_startup_ttyout')\"]] ..[[ -c q | cat -v"]] -- Output to a pipe. ..[[, shellescape(v:progpath))]]) retry(nil, 3000, function() sleep(1) eq('1\n0\n', -- stdin is a TTY, stdout is a pipe read_file('Xtest_startup_ttyout')) end) end) it('input from pipe: has("ttyin")==0 has("ttyout")==1', function() if iswin() then command([[set shellcmdflag=/s\ /c shellxquote=\"]]) end -- Running in :terminal command([[exe printf("terminal echo foo | ]] -- Input from a pipe. ..[[%s -u NONE -i NONE --cmd \"]] ..nvim_set..[[\"]] ..[[ -c \"call writefile([has('ttyin'), has('ttyout')], 'Xtest_startup_ttyout')\"]] ..[[ -c q -- -"]] ..[[, shellescape(v:progpath))]]) retry(nil, 3000, function() sleep(1) eq('0\n1\n', -- stdin is a pipe, stdout is a TTY read_file('Xtest_startup_ttyout')) end) end) it('input from pipe (implicit) #7679', function() local screen = Screen.new(25, 4) screen:attach() if iswin() then command([[set shellcmdflag=/s\ /c shellxquote=\"]]) end -- Running in :terminal command([[exe printf("terminal echo foo | ]] -- Input from a pipe. ..[[%s -u NONE -i NONE --cmd \"]] ..nvim_set..[[\"]] ..[[ -c \"echo has('ttyin') has('ttyout')\""]] ..[[, shellescape(v:progpath))]]) screen:expect([[ ^foo | ~ | 0 1 | | ]]) end) it('input from pipe + file args #7679', function() eq('ohyeah\r\n0 0 bufs=3', funcs.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', funcs.system({nvim_prog, '-n', '-u', 'NONE', '-i', 'NONE', '--headless', '+ls!', '+qall!', '-', 'file1', 'file2', }, { '' })) end) it('-e/-E interactive #7679', function() clear('-e') local screen = Screen.new(25, 3) screen:attach() feed("put ='from -e'") screen:expect([[ :put ='from -e' | from -e | :^ | ]]) clear('-E') screen = Screen.new(25, 3) screen:attach() feed("put ='from -E'") screen:expect([[ :put ='from -E' | from -E | :^ | ]]) 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', funcs.system({nvim_prog, '-n', '-u', 'NONE', '-i', 'NONE', '-Es', '+.print', 'test/functional/fixtures/tty-test.c' }, { 'partylikeits1999', '' })) eq(inputstr, funcs.system({nvim_prog, '-i', 'NONE', '-Es', '+%print', '-' }, input)) -- with `-u NORC` eq('thepartycontinues\n', funcs.system({nvim_prog, '-n', '-u', 'NORC', '-Es', '+.print' }, { 'thepartycontinues', '' })) -- without `-u` eq('thepartycontinues\n', funcs.system({nvim_prog, '-n', '-Es', '+.print' }, { 'thepartycontinues', '' })) -- -- -es: read stdin as ex-commands -- eq(' encoding=utf-8\n', funcs.system({nvim_prog, '-n', '-u', 'NONE', '-i', 'NONE', '-es', 'test/functional/fixtures/tty-test.c' }, { 'set encoding', '' })) eq('line1\nline2\n', funcs.system({nvim_prog, '-i', 'NONE', '-es', '-' }, input)) -- with `-u NORC` eq(' encoding=utf-8\n', funcs.system({nvim_prog, '-n', '-u', 'NORC', '-es' }, { 'set encoding', '' })) -- without `-u` eq(' encoding=utf-8\n', funcs.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 = funcs.system({nvim_prog, arg, '+set swapfile? updatecount? shada?', "+put =execute('scriptnames')", '+%print'}) local line1 = string.match(out, '^.-\n') -- updatecount=0 means swapfile was disabled. eq(" swapfile updatecount=0 shada=!,'100,<50,s10,h\n", line1) -- Standard plugins were loaded, but not user config. eq('health.vim', string.match(out, 'health.vim')) eq(nil, string.match(out, 'init.vim')) end end) it('fails on --embed with -es/-Es', function() matches('nvim[.exe]*: %-%-embed conflicts with %-es/%-Es', funcs.system({nvim_prog, '--embed', '-es' })) matches('nvim[.exe]*: %-%-embed conflicts with %-es/%-Es', funcs.system({nvim_prog, '--embed', '-Es' })) end) it('does not crash if --embed is given twice', function() clear{args={'--embed'}} eq(2, eval('1+1')) end) it('does not crash when expanding cdpath during early_init', function() clear{env={CDPATH='~doesnotexist'}} eq(',~doesnotexist', eval('&cdpath')) end) it('ENTER dismisses early message #7967', function() local screen screen = Screen.new(60, 6) screen:attach() command([[let g:id = termopen('"]]..nvim_prog.. [[" -u NONE -i NONE --cmd "set noruler" --cmd "let g:foo = g:bar"')]]) screen:expect([[ ^ | Error detected while processing pre-vimrc command line: | E121: Undefined variable: g:bar | E15: Invalid expression: g:bar | Press ENTER or type command to continue | | ]]) command([[call chansend(g:id, "\n")]]) screen:expect([[ ^ | ~ | ~ | [No Name] | | | ]]) 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) 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. funcs.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 = funcs.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('sysinit', function() local xdgdir = 'Xxdg' local vimdir = 'Xvim' local xhome = 'Xhome' local pathsep = helpers.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('clean', function() clear() ok(string.match(meths.get_option('runtimepath'), funcs.stdpath('config')) ~= nil) clear('--clean') ok(string.match(meths.get_option('runtimepath'), funcs.stdpath('config')) == nil) end)