aboutsummaryrefslogtreecommitdiff
path: root/test/functional/api/vim_spec.lua
diff options
context:
space:
mode:
Diffstat (limited to 'test/functional/api/vim_spec.lua')
-rw-r--r--test/functional/api/vim_spec.lua216
1 files changed, 196 insertions, 20 deletions
diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua
index 8b77dbcaa6..72e810e3e4 100644
--- a/test/functional/api/vim_spec.lua
+++ b/test/functional/api/vim_spec.lua
@@ -16,11 +16,14 @@ local parse_context = helpers.parse_context
local request = helpers.request
local source = helpers.source
local next_msg = helpers.next_msg
+local tmpname = helpers.tmpname
+local write_file = helpers.write_file
local pcall_err = helpers.pcall_err
local format_string = helpers.format_string
local intchar2lua = helpers.intchar2lua
local mergedicts_copy = helpers.mergedicts_copy
+local endswith = helpers.endswith
describe('API', function()
before_each(clear)
@@ -74,9 +77,127 @@ describe('API', function()
eq({mode='i', blocking=false}, nvim("get_mode"))
end)
+ describe('nvim_exec', function()
+ it('one-line input', function()
+ nvim('exec', "let x1 = 'a'", false)
+ eq('a', nvim('get_var', 'x1'))
+ end)
+
+ it(':verbose set {option}?', function()
+ nvim('exec', 'set nowrap', false)
+ eq('nowrap\n\tLast set from anonymous :source',
+ nvim('exec', 'verbose set wrap?', true))
+ end)
+
+ it('multiline input', function()
+ -- Heredoc + empty lines.
+ nvim('exec', "let x2 = 'a'\n", false)
+ eq('a', nvim('get_var', 'x2'))
+ nvim('exec','lua <<EOF\n\n\n\ny=3\n\n\nEOF', false)
+ eq(3, nvim('eval', "luaeval('y')"))
+
+ eq('', nvim('exec', 'lua <<EOF\ny=3\nEOF', false))
+ eq(3, nvim('eval', "luaeval('y')"))
+
+ -- Multiple statements
+ nvim('exec', 'let x1=1\nlet x2=2\nlet x3=3\n', false)
+ eq(1, nvim('eval', 'x1'))
+ eq(2, nvim('eval', 'x2'))
+ eq(3, nvim('eval', 'x3'))
+
+ -- Functions
+ nvim('exec', 'function Foo()\ncall setline(1,["xxx"])\nendfunction', false)
+ eq(nvim('get_current_line'), '')
+ nvim('exec', 'call Foo()', false)
+ eq(nvim('get_current_line'), 'xxx')
+
+ -- Autocmds
+ nvim('exec','autocmd BufAdd * :let x1 = "Hello"', false)
+ nvim('command', 'new foo')
+ eq('Hello', request('nvim_eval', 'g:x1'))
+ end)
+
+ it('non-ASCII input', function()
+ nvim('exec', [=[
+ new
+ exe "normal! i ax \n Ax "
+ :%s/ax/--a1234--/g | :%s/Ax/--A1234--/g
+ ]=], false)
+ nvim('command', '1')
+ eq(' --a1234-- ', nvim('get_current_line'))
+ nvim('command', '2')
+ eq(' --A1234-- ', nvim('get_current_line'))
+
+ nvim('exec', [[
+ new
+ call setline(1,['xxx'])
+ call feedkeys('r')
+ call feedkeys('ñ', 'xt')
+ ]], false)
+ eq('ñxx', nvim('get_current_line'))
+ end)
+
+ it('execution error', function()
+ eq('Vim:E492: Not an editor command: bogus_command',
+ pcall_err(request, 'nvim_exec', 'bogus_command', false))
+ eq('', nvim('eval', 'v:errmsg')) -- v:errmsg was not updated.
+ eq('', eval('v:exception'))
+
+ eq('Vim(buffer):E86: Buffer 23487 does not exist',
+ pcall_err(request, 'nvim_exec', 'buffer 23487', false))
+ eq('', eval('v:errmsg')) -- v:errmsg was not updated.
+ eq('', eval('v:exception'))
+ end)
+
+ it('recursion', function()
+ local fname = tmpname()
+ write_file(fname, 'let x1 = "set from :source file"\n')
+ -- nvim_exec
+ -- :source
+ -- nvim_exec
+ request('nvim_exec', [[
+ let x2 = substitute('foo','o','X','g')
+ let x4 = 'should be overwritten'
+ call nvim_exec("source ]]..fname..[[\nlet x3 = substitute('foo','foo','set by recursive nvim_exec','g')\nlet x5='overwritten'\nlet x4=x5\n", v:false)
+ ]], false)
+ eq('set from :source file', request('nvim_get_var', 'x1'))
+ eq('fXX', request('nvim_get_var', 'x2'))
+ eq('set by recursive nvim_exec', request('nvim_get_var', 'x3'))
+ eq('overwritten', request('nvim_get_var', 'x4'))
+ eq('overwritten', request('nvim_get_var', 'x5'))
+ os.remove(fname)
+ end)
+
+ it('traceback', function()
+ local fname = tmpname()
+ write_file(fname, 'echo "hello"\n')
+ local sourcing_fname = tmpname()
+ write_file(sourcing_fname, 'call nvim_exec("source '..fname..'", v:false)\n')
+ meths.exec('set verbose=2', false)
+ local traceback_output = 'line 0: sourcing "'..sourcing_fname..'"\n'..
+ 'line 0: sourcing "'..fname..'"\n'..
+ 'hello\n'..
+ 'finished sourcing '..fname..'\n'..
+ 'continuing in nvim_exec() called at '..sourcing_fname..':1\n'..
+ 'finished sourcing '..sourcing_fname..'\n'..
+ 'continuing in nvim_exec() called at nvim_exec():0'
+ eq(traceback_output,
+ meths.exec('call nvim_exec("source '..sourcing_fname..'", v:false)', true))
+ os.remove(fname)
+ os.remove(sourcing_fname)
+ end)
+
+ it('returns output', function()
+ eq('this is spinal tap',
+ nvim('exec', 'lua <<EOF\n\n\nprint("this is spinal tap")\n\n\nEOF', true))
+ eq('', nvim('exec', 'echo', true))
+ eq('foo 42', nvim('exec', 'echo "foo" 42', true))
+ end)
+ end)
+
describe('nvim_command', function()
it('works', function()
- local fname = helpers.tmpname()
+ local fname = tmpname()
nvim('command', 'new')
nvim('command', 'edit '..fname)
nvim('command', 'normal itesting\napi')
@@ -313,41 +434,44 @@ describe('API', function()
end)
end)
- describe('nvim_execute_lua', function()
+ describe('nvim_exec_lua', function()
it('works', function()
- meths.execute_lua('vim.api.nvim_set_var("test", 3)', {})
+ meths.exec_lua('vim.api.nvim_set_var("test", 3)', {})
eq(3, meths.get_var('test'))
- eq(17, meths.execute_lua('a, b = ...\nreturn a + b', {10,7}))
+ eq(17, meths.exec_lua('a, b = ...\nreturn a + b', {10,7}))
- eq(NIL, meths.execute_lua('function xx(a,b)\nreturn a..b\nend',{}))
+ eq(NIL, meths.exec_lua('function xx(a,b)\nreturn a..b\nend',{}))
+ eq("xy", meths.exec_lua('return xx(...)', {'x','y'}))
+
+ -- Deprecated name: nvim_execute_lua.
eq("xy", meths.execute_lua('return xx(...)', {'x','y'}))
end)
it('reports errors', function()
eq([[Error loading lua: [string "<nvim>"]:1: '=' expected near '+']],
- pcall_err(meths.execute_lua, 'a+*b', {}))
+ pcall_err(meths.exec_lua, 'a+*b', {}))
eq([[Error loading lua: [string "<nvim>"]:1: unexpected symbol near '1']],
- pcall_err(meths.execute_lua, '1+2', {}))
+ pcall_err(meths.exec_lua, '1+2', {}))
eq([[Error loading lua: [string "<nvim>"]:1: unexpected symbol]],
- pcall_err(meths.execute_lua, 'aa=bb\0', {}))
+ pcall_err(meths.exec_lua, 'aa=bb\0', {}))
eq([[Error executing lua: [string "<nvim>"]:1: attempt to call global 'bork' (a nil value)]],
- pcall_err(meths.execute_lua, 'bork()', {}))
+ pcall_err(meths.exec_lua, 'bork()', {}))
eq('Error executing lua: [string "<nvim>"]:1: did\nthe\nfail',
- pcall_err(meths.execute_lua, 'error("did\\nthe\\nfail")', {}))
+ pcall_err(meths.exec_lua, 'error("did\\nthe\\nfail")', {}))
end)
it('uses native float values', function()
- eq(2.5, meths.execute_lua("return select(1, ...)", {2.5}))
- eq("2.5", meths.execute_lua("return vim.inspect(...)", {2.5}))
+ eq(2.5, meths.exec_lua("return select(1, ...)", {2.5}))
+ eq("2.5", meths.exec_lua("return vim.inspect(...)", {2.5}))
-- "special" float values are still accepted as return values.
- eq(2.5, meths.execute_lua("return vim.api.nvim_eval('2.5')", {}))
- eq("{\n [false] = 2.5,\n [true] = 3\n}", meths.execute_lua("return vim.inspect(vim.api.nvim_eval('2.5'))", {}))
+ eq(2.5, meths.exec_lua("return vim.api.nvim_eval('2.5')", {}))
+ eq("{\n [false] = 2.5,\n [true] = 3\n}", meths.exec_lua("return vim.inspect(vim.api.nvim_eval('2.5'))", {}))
end)
end)
@@ -358,6 +482,11 @@ describe('API', function()
eq(true, status) -- nvim_input() did not fail.
eq("E117:", v_errnum) -- v:errmsg was updated.
end)
+
+ it('does not crash even if trans_special result is largest #11788, #12287', function()
+ command("call nvim_input('<M-'.nr2char(0x40000000).'>')")
+ eq(1, eval('1'))
+ end)
end)
describe('nvim_paste', function()
@@ -447,13 +576,35 @@ describe('API', function()
eq({0,7,1,0}, funcs.getpos('.'))
eq(false, nvim('get_option', 'paste'))
end)
+ it('Replace-mode', function()
+ -- Within single line
+ nvim('put', {'aabbccdd', 'eeffgghh', 'iijjkkll'}, "c", true, false)
+ command('normal l')
+ command('startreplace')
+ nvim('paste', '123456', true, -1)
+ expect([[
+ a123456d
+ eeffgghh
+ iijjkkll]])
+ command('%delete _')
+ -- Across lines
+ nvim('put', {'aabbccdd', 'eeffgghh', 'iijjkkll'}, "c", true, false)
+ command('normal l')
+ command('startreplace')
+ nvim('paste', '123\n456', true, -1)
+ expect([[
+ a123
+ 456d
+ eeffgghh
+ iijjkkll]])
+ end)
it('crlf=false does not break lines at CR, CRLF', function()
nvim('paste', 'line 1\r\n\r\rline 2\nline 3\rline 4\r', false, -1)
expect('line 1\r\n\r\rline 2\nline 3\rline 4\r')
eq({0,3,14,0}, funcs.getpos('.'))
end)
it('vim.paste() failure', function()
- nvim('execute_lua', 'vim.paste = (function(lines, phase) error("fake fail") end)', {})
+ nvim('exec_lua', 'vim.paste = (function(lines, phase) error("fake fail") end)', {})
eq([[Error executing lua: [string "<nvim>"]:1: fake fail]],
pcall_err(request, 'nvim_paste', 'line 1\nline 2\nline 3', false, 1))
end)
@@ -677,7 +828,7 @@ describe('API', function()
ok(nil ~= string.find(rv, 'noequalalways\n'..
'\tLast set from API client %(channel id %d+%)'))
- nvim('execute_lua', 'vim.api.nvim_set_option("equalalways", true)', {})
+ nvim('exec_lua', 'vim.api.nvim_set_option("equalalways", true)', {})
status, rv = pcall(nvim, 'command_output',
'verbose set equalalways?')
eq(true, status)
@@ -1662,7 +1813,7 @@ describe('API', function()
eq({id=1}, meths.get_current_buf())
end)
- it("doesn't cause BufEnter or BufWinEnter autocmds", function()
+ it("does not trigger BufEnter, BufWinEnter", function()
command("let g:fired = v:false")
command("au BufEnter,BufWinEnter * let g:fired = v:true")
@@ -1672,7 +1823,7 @@ describe('API', function()
eq(false, eval('g:fired'))
end)
- it('|scratch-buffer|', function()
+ it('scratch-buffer', function()
eq({id=2}, meths.create_buf(false, true))
eq({id=3}, meths.create_buf(true, true))
eq({id=4}, meths.create_buf(true, true))
@@ -1680,7 +1831,7 @@ describe('API', function()
eq(' 1 %a "[No Name]" line 1\n'..
' 3 h "[Scratch]" line 0\n'..
' 4 h "[Scratch]" line 0',
- meths.command_output("ls"))
+ meths.exec('ls', true))
-- current buffer didn't change
eq({id=1}, meths.get_current_buf())
@@ -1699,6 +1850,7 @@ describe('API', function()
eq('nofile', meths.buf_get_option(b, 'buftype'))
eq('hide', meths.buf_get_option(b, 'bufhidden'))
eq(false, meths.buf_get_option(b, 'swapfile'))
+ eq(false, meths.buf_get_option(b, 'modeline'))
end
--
@@ -1714,8 +1866,9 @@ describe('API', function()
eq('nofile', meths.buf_get_option(edited_buf, 'buftype'))
eq('hide', meths.buf_get_option(edited_buf, 'bufhidden'))
eq(false, meths.buf_get_option(edited_buf, 'swapfile'))
+ eq(false, meths.buf_get_option(edited_buf, 'modeline'))
- -- scratch buffer can be wiped without error
+ -- Scratch buffer can be wiped without error.
command('bwipe')
screen:expect([[
^ |
@@ -1730,4 +1883,27 @@ describe('API', function()
command('silent! call nvim_create_buf(0, 1)')
end)
end)
+
+ describe('nvim_get_runtime_file', function()
+ it('works', function()
+ eq({}, meths.get_runtime_file("bork.borkbork", false))
+ eq({}, meths.get_runtime_file("bork.borkbork", true))
+ eq(1, #meths.get_runtime_file("autoload/msgpack.vim", false))
+ eq(1, #meths.get_runtime_file("autoload/msgpack.vim", true))
+ local val = meths.get_runtime_file("autoload/remote/*.vim", true)
+ eq(2, #val)
+ local p = helpers.alter_slashes
+ if endswith(val[1], "define.vim") then
+ ok(endswith(val[1], p("autoload/remote/define.vim")))
+ ok(endswith(val[2], p("autoload/remote/host.vim")))
+ else
+ ok(endswith(val[1], p("autoload/remote/host.vim")))
+ ok(endswith(val[2], p("autoload/remote/define.vim")))
+ end
+ val = meths.get_runtime_file("autoload/remote/*.vim", false)
+ eq(1, #val)
+ ok(endswith(val[1], p("autoload/remote/define.vim"))
+ or endswith(val[1], p("autoload/remote/host.vim")))
+ end)
+ end)
end)