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.lua3895
1 files changed, 2150 insertions, 1745 deletions
diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua
index 8bbadda9b0..9a4a457637 100644
--- a/test/functional/api/vim_spec.lua
+++ b/test/functional/api/vim_spec.lua
@@ -1,22 +1,25 @@
local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
-local luv = require('luv')
+local uv = vim.uv
local fmt = string.format
+local dedent = helpers.dedent
local assert_alive = helpers.assert_alive
-local NIL = helpers.NIL
-local clear, nvim, eq, neq = helpers.clear, helpers.nvim, helpers.eq, helpers.neq
+local NIL = vim.NIL
+local clear, eq, neq = helpers.clear, helpers.eq, helpers.neq
local command = helpers.command
+local command_output = helpers.api.nvim_command_output
local exec = helpers.exec
local exec_capture = helpers.exec_capture
local eval = helpers.eval
local expect = helpers.expect
-local funcs = helpers.funcs
-local meths = helpers.meths
+local fn = helpers.fn
+local api = helpers.api
local matches = helpers.matches
-local pesc = helpers.pesc
+local pesc = vim.pesc
local mkdir_p = helpers.mkdir_p
local ok, nvim_async, feed = helpers.ok, helpers.nvim_async, helpers.feed
+local async_meths = helpers.async_meths
local is_os = helpers.is_os
local parse_context = helpers.parse_context
local request = helpers.request
@@ -31,203 +34,273 @@ local insert = helpers.insert
local skip = helpers.skip
local pcall_err = helpers.pcall_err
-local format_string = helpers.format_string
+local format_string = require('test.format_string').format_string
local intchar2lua = helpers.intchar2lua
local mergedicts_copy = helpers.mergedicts_copy
-local endswith = helpers.endswith
+local endswith = vim.endswith
describe('API', function()
before_each(clear)
it('validates requests', function()
-- RPC
- matches('Invalid method: bogus$',
- pcall_err(request, 'bogus'))
- matches('Invalid method: … の り 。…$',
- pcall_err(request, '… の り 。…'))
- matches('Invalid method: <empty>$',
- pcall_err(request, ''))
+ matches('Invalid method: bogus$', pcall_err(request, 'bogus'))
+ matches('Invalid method: … の り 。…$', pcall_err(request, '… の り 。…'))
+ matches('Invalid method: <empty>$', pcall_err(request, ''))
-- Non-RPC: rpcrequest(v:servername) uses internal channel.
- matches('Invalid method: … の り 。…$',
- pcall_err(request, 'nvim_eval',
- [=[rpcrequest(sockconnect('pipe', v:servername, {'rpc':1}), '… の り 。…')]=]))
- matches('Invalid method: bogus$',
- pcall_err(request, 'nvim_eval',
- [=[rpcrequest(sockconnect('pipe', v:servername, {'rpc':1}), 'bogus')]=]))
+ matches(
+ 'Invalid method: … の り 。…$',
+ pcall_err(
+ request,
+ 'nvim_eval',
+ [=[rpcrequest(sockconnect('pipe', v:servername, {'rpc':1}), '… の り 。…')]=]
+ )
+ )
+ matches(
+ 'Invalid method: bogus$',
+ pcall_err(
+ request,
+ 'nvim_eval',
+ [=[rpcrequest(sockconnect('pipe', v:servername, {'rpc':1}), 'bogus')]=]
+ )
+ )
-- XXX: This must be the last one, else next one will fail:
-- "Packer instance already working. Use another Packer ..."
- matches("can't serialize object of type .$",
- pcall_err(request, nil))
+ matches("can't serialize object of type .$", pcall_err(request, nil))
end)
it('handles errors in async requests', function()
- local error_types = meths.get_api_info()[2].error_types
+ local error_types = api.nvim_get_api_info()[2].error_types
nvim_async('bogus')
- eq({'notification', 'nvim_error_event',
- {error_types.Exception.id, 'Invalid method: nvim_bogus'}}, next_msg())
+ eq({
+ 'notification',
+ 'nvim_error_event',
+ { error_types.Exception.id, 'Invalid method: bogus' },
+ }, next_msg())
-- error didn't close channel.
assert_alive()
end)
it('failed async request emits nvim_error_event', function()
- local error_types = meths.get_api_info()[2].error_types
- nvim_async('command', 'bogus')
- eq({'notification', 'nvim_error_event',
- {error_types.Exception.id, 'Vim:E492: Not an editor command: bogus'}},
- next_msg())
+ local error_types = api.nvim_get_api_info()[2].error_types
+ async_meths.nvim_command('bogus')
+ eq({
+ 'notification',
+ 'nvim_error_event',
+ { error_types.Exception.id, 'Vim:E492: Not an editor command: bogus' },
+ }, next_msg())
-- error didn't close channel.
assert_alive()
end)
+ it('input is processed first when followed immediately by non-fast events', function()
+ api.nvim_set_current_line('ab')
+ async_meths.nvim_input('x')
+ async_meths.nvim_exec_lua('_G.res1 = vim.api.nvim_get_current_line()', {})
+ async_meths.nvim_exec_lua('_G.res2 = vim.api.nvim_get_current_line()', {})
+ eq({ 'b', 'b' }, exec_lua('return { _G.res1, _G.res2 }'))
+ end)
+
it('does not set CA_COMMAND_BUSY #7254', function()
- nvim('command', 'split')
- nvim('command', 'autocmd WinEnter * startinsert')
- nvim('command', 'wincmd w')
- eq({mode='i', blocking=false}, nvim("get_mode"))
+ command('split')
+ command('autocmd WinEnter * startinsert')
+ command('wincmd w')
+ eq({ mode = 'i', blocking = false }, api.nvim_get_mode())
end)
describe('nvim_exec2', function()
it('always returns table', function()
-- In built version this results into `vim.empty_dict()`
- eq({}, nvim('exec2', 'echo "Hello"', {}))
- eq({}, nvim('exec2', 'echo "Hello"', { output = false }))
- eq({ output = 'Hello' }, nvim('exec2', 'echo "Hello"', { output = true }))
+ eq({}, api.nvim_exec2('echo "Hello"', {}))
+ eq({}, api.nvim_exec2('echo "Hello"', { output = false }))
+ eq({ output = 'Hello' }, api.nvim_exec2('echo "Hello"', { output = true }))
end)
it('default options', function()
-- Should be equivalent to { output = false }
- nvim('exec2', "let x0 = 'a'", {})
- eq('a', nvim('get_var', 'x0'))
+ api.nvim_exec2("let x0 = 'a'", {})
+ eq('a', api.nvim_get_var('x0'))
end)
it('one-line input', function()
- nvim('exec2', "let x1 = 'a'", { output = false })
- eq('a', nvim('get_var', 'x1'))
+ api.nvim_exec2("let x1 = 'a'", { output = false })
+ eq('a', api.nvim_get_var('x1'))
end)
it(':verbose set {option}?', function()
- nvim('exec2', 'set nowrap', { output = false })
- eq({ output = 'nowrap\n\tLast set from anonymous :source' },
- nvim('exec2', 'verbose set wrap?', { output = true }))
+ api.nvim_exec2('set nowrap', { output = false })
+ eq(
+ { output = 'nowrap\n\tLast set from anonymous :source' },
+ api.nvim_exec2('verbose set wrap?', { output = true })
+ )
-- Using script var to force creation of a script item
- nvim('exec2', [[
+ api.nvim_exec2(
+ [[
let s:a = 1
set nowrap
- ]], { output = false })
- eq({ output = 'nowrap\n\tLast set from anonymous :source (script id 1)' },
- nvim('exec2', 'verbose set wrap?', { output = true }))
+ ]],
+ { output = false }
+ )
+ eq(
+ { output = 'nowrap\n\tLast set from anonymous :source (script id 1)' },
+ api.nvim_exec2('verbose set wrap?', { output = true })
+ )
end)
it('multiline input', function()
-- Heredoc + empty lines.
- nvim('exec2', "let x2 = 'a'\n", { output = false })
- eq('a', nvim('get_var', 'x2'))
- nvim('exec2','lua <<EOF\n\n\n\ny=3\n\n\nEOF', { output = false })
- eq(3, nvim('eval', "luaeval('y')"))
+ api.nvim_exec2("let x2 = 'a'\n", { output = false })
+ eq('a', api.nvim_get_var('x2'))
+ api.nvim_exec2('lua <<EOF\n\n\n\ny=3\n\n\nEOF', { output = false })
+ eq(3, api.nvim_eval("luaeval('y')"))
- eq({}, nvim('exec2', 'lua <<EOF\ny=3\nEOF', { output = false }))
- eq(3, nvim('eval', "luaeval('y')"))
+ eq({}, api.nvim_exec2('lua <<EOF\ny=3\nEOF', { output = false }))
+ eq(3, api.nvim_eval("luaeval('y')"))
-- Multiple statements
- nvim('exec2', 'let x1=1\nlet x2=2\nlet x3=3\n', { output = false })
- eq(1, nvim('eval', 'x1'))
- eq(2, nvim('eval', 'x2'))
- eq(3, nvim('eval', 'x3'))
+ api.nvim_exec2('let x1=1\nlet x2=2\nlet x3=3\n', { output = false })
+ eq(1, api.nvim_eval('x1'))
+ eq(2, api.nvim_eval('x2'))
+ eq(3, api.nvim_eval('x3'))
-- Functions
- nvim('exec2', 'function Foo()\ncall setline(1,["xxx"])\nendfunction', { output = false })
- eq('', nvim('get_current_line'))
- nvim('exec2', 'call Foo()', { output = false })
- eq('xxx', nvim('get_current_line'))
+ api.nvim_exec2('function Foo()\ncall setline(1,["xxx"])\nendfunction', { output = false })
+ eq('', api.nvim_get_current_line())
+ api.nvim_exec2('call Foo()', { output = false })
+ eq('xxx', api.nvim_get_current_line())
-- Autocmds
- nvim('exec2','autocmd BufAdd * :let x1 = "Hello"', { output = false })
- nvim('command', 'new foo')
+ api.nvim_exec2('autocmd BufAdd * :let x1 = "Hello"', { output = false })
+ command('new foo')
eq('Hello', request('nvim_eval', 'g:x1'))
-- Line continuations
- nvim('exec2', [[
+ api.nvim_exec2(
+ [[
let abc = #{
\ a: 1,
"\ b: 2,
\ c: 3
- \ }]], { output = false })
- eq({a = 1, c = 3}, request('nvim_eval', 'g:abc'))
+ \ }]],
+ { output = false }
+ )
+ eq({ a = 1, c = 3 }, request('nvim_eval', 'g:abc'))
-- try no spaces before continuations to catch off-by-one error
- nvim('exec2', 'let ab = #{\n\\a: 98,\n"\\ b: 2\n\\}', { output = false })
- eq({a = 98}, request('nvim_eval', 'g:ab'))
+ api.nvim_exec2('let ab = #{\n\\a: 98,\n"\\ b: 2\n\\}', { output = false })
+ eq({ a = 98 }, request('nvim_eval', 'g:ab'))
-- Script scope (s:)
- eq({ output = 'ahoy! script-scoped varrrrr' }, nvim('exec2', [[
+ eq(
+ { output = 'ahoy! script-scoped varrrrr' },
+ api.nvim_exec2(
+ [[
let s:pirate = 'script-scoped varrrrr'
function! s:avast_ye_hades(s) abort
return a:s .. ' ' .. s:pirate
endfunction
echo <sid>avast_ye_hades('ahoy!')
- ]], { output = true }))
-
- eq({ output = "{'output': 'ahoy! script-scoped varrrrr'}" }, nvim('exec2', [[
+ ]],
+ { output = true }
+ )
+ )
+
+ eq(
+ { output = "{'output': 'ahoy! script-scoped varrrrr'}" },
+ api.nvim_exec2(
+ [[
let s:pirate = 'script-scoped varrrrr'
function! Avast_ye_hades(s) abort
return a:s .. ' ' .. s:pirate
endfunction
echo nvim_exec2('echo Avast_ye_hades(''ahoy!'')', {'output': v:true})
- ]], { output = true }))
-
- matches('Vim%(echo%):E121: Undefined variable: s:pirate$',
- pcall_err(request, 'nvim_exec2', [[
+ ]],
+ { output = true }
+ )
+ )
+
+ matches(
+ 'Vim%(echo%):E121: Undefined variable: s:pirate$',
+ pcall_err(
+ request,
+ 'nvim_exec2',
+ [[
let s:pirate = 'script-scoped varrrrr'
call nvim_exec2('echo s:pirate', {'output': v:true})
- ]], { output = false }))
+ ]],
+ { output = false }
+ )
+ )
-- Script items are created only on script var access
- eq({ output = '1\n0' }, nvim('exec2', [[
+ eq(
+ { output = '1\n0' },
+ api.nvim_exec2(
+ [[
echo expand("<SID>")->empty()
let s:a = 123
echo expand("<SID>")->empty()
- ]], { output = true }))
-
- eq({ output = '1\n0' }, nvim('exec2', [[
+ ]],
+ { output = true }
+ )
+ )
+
+ eq(
+ { output = '1\n0' },
+ api.nvim_exec2(
+ [[
echo expand("<SID>")->empty()
function s:a() abort
endfunction
echo expand("<SID>")->empty()
- ]], { output = true }))
+ ]],
+ { output = true }
+ )
+ )
end)
it('non-ASCII input', function()
- nvim('exec2', [=[
+ api.nvim_exec2(
+ [=[
new
exe "normal! i ax \n Ax "
:%s/ax/--a1234--/g | :%s/Ax/--A1234--/g
- ]=], { output = false })
- nvim('command', '1')
- eq(' --a1234-- ', nvim('get_current_line'))
- nvim('command', '2')
- eq(' --A1234-- ', nvim('get_current_line'))
-
- nvim('exec2', [[
+ ]=],
+ { output = false }
+ )
+ command('1')
+ eq(' --a1234-- ', api.nvim_get_current_line())
+ command('2')
+ eq(' --A1234-- ', api.nvim_get_current_line())
+
+ api.nvim_exec2(
+ [[
new
call setline(1,['xxx'])
call feedkeys('r')
call feedkeys('ñ', 'xt')
- ]], { output = false })
- eq('ñxx', nvim('get_current_line'))
+ ]],
+ { output = false }
+ )
+ eq('ñxx', api.nvim_get_current_line())
end)
it('execution error', function()
- eq('nvim_exec2(): Vim:E492: Not an editor command: bogus_command',
- pcall_err(request, 'nvim_exec2', 'bogus_command', {}))
- eq('', nvim('eval', 'v:errmsg')) -- v:errmsg was not updated.
+ eq(
+ 'nvim_exec2(): Vim:E492: Not an editor command: bogus_command',
+ pcall_err(request, 'nvim_exec2', 'bogus_command', {})
+ )
+ eq('', api.nvim_eval('v:errmsg')) -- v:errmsg was not updated.
eq('', eval('v:exception'))
- eq('nvim_exec2(): Vim(buffer):E86: Buffer 23487 does not exist',
- pcall_err(request, 'nvim_exec2', 'buffer 23487', {}))
- eq('', eval('v:errmsg')) -- v:errmsg was not updated.
+ eq(
+ 'nvim_exec2(): Vim(buffer):E86: Buffer 23487 does not exist',
+ pcall_err(request, 'nvim_exec2', 'buffer 23487', {})
+ )
+ eq('', eval('v:errmsg')) -- v:errmsg was not updated.
eq('', eval('v:exception'))
end)
@@ -240,7 +313,7 @@ describe('API', function()
request('nvim_exec2', [[
let x2 = substitute('foo','o','X','g')
let x4 = 'should be overwritten'
- call nvim_exec2("source ]]..fname..[[\nlet x3 = substitute('foo','foo','set by recursive nvim_exec2','g')\nlet x5='overwritten'\nlet x4=x5\n", {'output': v:false})
+ call nvim_exec2("source ]] .. fname .. [[\nlet x3 = substitute('foo','foo','set by recursive nvim_exec2','g')\nlet x5='overwritten'\nlet x4=x5\n", {'output': v:false})
]], { output = false })
eq('set from :source file', request('nvim_get_var', 'x1'))
eq('fXX', request('nvim_get_var', 'x2'))
@@ -254,86 +327,108 @@ describe('API', function()
local fname = tmpname()
write_file(fname, 'echo "hello"\n')
local sourcing_fname = tmpname()
- write_file(sourcing_fname, 'call nvim_exec2("source '..fname..'", {"output": v:false})\n')
- meths.exec2('set verbose=2', { output = false })
- local traceback_output = 'line 0: sourcing "'..sourcing_fname..'"\n'..
- 'line 0: sourcing "'..fname..'"\n'..
- 'hello\n'..
- 'finished sourcing '..fname..'\n'..
- 'continuing in nvim_exec2() called at '..sourcing_fname..':1\n'..
- 'finished sourcing '..sourcing_fname..'\n'..
- 'continuing in nvim_exec2() called at nvim_exec2():0'
- eq({ output = traceback_output },
- meths.exec2('call nvim_exec2("source '..sourcing_fname..'", {"output": v:false})', { output = true }))
+ write_file(sourcing_fname, 'call nvim_exec2("source ' .. fname .. '", {"output": v:false})\n')
+ api.nvim_exec2('set verbose=2', { output = false })
+ local traceback_output = dedent([[
+ line 0: sourcing "%s"
+ line 0: sourcing "%s"
+ hello
+ finished sourcing %s
+ continuing in nvim_exec2() called at %s:1
+ finished sourcing %s
+ continuing in nvim_exec2() called at nvim_exec2():0]]):format(
+ sourcing_fname,
+ fname,
+ fname,
+ sourcing_fname,
+ sourcing_fname
+ )
+ eq(
+ { output = traceback_output },
+ api.nvim_exec2(
+ 'call nvim_exec2("source ' .. sourcing_fname .. '", {"output": v:false})',
+ { output = true }
+ )
+ )
os.remove(fname)
os.remove(sourcing_fname)
end)
it('returns output', function()
- eq({ output = 'this is spinal tap' },
- nvim('exec2', 'lua <<EOF\n\n\nprint("this is spinal tap")\n\n\nEOF', { output = true }))
- eq({ output = '' }, nvim('exec2', 'echo', { output = true }))
- eq({ output = 'foo 42' }, nvim('exec2', 'echo "foo" 42', { output = true }))
+ eq(
+ { output = 'this is spinal tap' },
+ api.nvim_exec2('lua <<EOF\n\n\nprint("this is spinal tap")\n\n\nEOF', { output = true })
+ )
+ eq({ output = '' }, api.nvim_exec2('echo', { output = true }))
+ eq({ output = 'foo 42' }, api.nvim_exec2('echo "foo" 42', { output = true }))
end)
it('displays messages when opts.output=false', function()
local screen = Screen.new(40, 8)
screen:attach()
screen:set_default_attr_ids({
- [0] = {bold=true, foreground=Screen.colors.Blue},
+ [0] = { bold = true, foreground = Screen.colors.Blue },
})
- meths.exec2("echo 'hello'", { output = false })
- screen:expect{grid=[[
+ api.nvim_exec2("echo 'hello'", { output = false })
+ screen:expect {
+ grid = [[
^ |
- {0:~ }|
- {0:~ }|
- {0:~ }|
- {0:~ }|
- {0:~ }|
- {0:~ }|
+ {0:~ }|*6
hello |
- ]]}
+ ]],
+ }
end)
- it('doesn\'t display messages when output=true', function()
+ it("doesn't display messages when output=true", function()
local screen = Screen.new(40, 6)
screen:attach()
screen:set_default_attr_ids({
- [0] = {bold=true, foreground=Screen.colors.Blue},
+ [0] = { bold = true, foreground = Screen.colors.Blue },
})
- meths.exec2("echo 'hello'", { output = true })
- screen:expect{grid=[[
+ api.nvim_exec2("echo 'hello'", { output = true })
+ screen:expect {
+ grid = [[
^ |
- {0:~ }|
- {0:~ }|
- {0:~ }|
- {0:~ }|
+ {0:~ }|*4
|
- ]]}
+ ]],
+ }
exec([[
func Print()
call nvim_exec2('echo "hello"', { 'output': v:true })
endfunc
]])
feed([[:echon 1 | call Print() | echon 5<CR>]])
- screen:expect{grid=[[
+ screen:expect {
+ grid = [[
^ |
- {0:~ }|
- {0:~ }|
- {0:~ }|
- {0:~ }|
+ {0:~ }|*4
15 |
- ]]}
+ ]],
+ }
+ end)
+
+ it('errors properly when command too recursive', function()
+ exec_lua([[
+ _G.success = false
+ vim.api.nvim_create_user_command('Test', function()
+ vim.api.nvim_exec2('Test', {})
+ _G.success = true
+ end, {})
+ ]])
+ pcall_err(command, 'Test')
+ assert_alive()
+ eq(false, exec_lua('return _G.success'))
end)
end)
describe('nvim_command', function()
it('works', function()
local fname = tmpname()
- nvim('command', 'new')
- nvim('command', 'edit '..fname)
- nvim('command', 'normal itesting\napi')
- nvim('command', 'w')
+ command('new')
+ command('edit ' .. fname)
+ command('normal itesting\napi')
+ command('w')
local f = assert(io.open(fname))
if is_os('win') then
eq('testing\r\napi\r\n', f:read('*a'))
@@ -345,158 +440,166 @@ describe('API', function()
end)
it('Vimscript validation error: fails with specific error', function()
- local status, rv = pcall(nvim, "command", "bogus_command")
- eq(false, status) -- nvim_command() failed.
- eq("E492:", string.match(rv, "E%d*:")) -- Vimscript error was returned.
- eq('', nvim('eval', 'v:errmsg')) -- v:errmsg was not updated.
+ local status, rv = pcall(command, 'bogus_command')
+ eq(false, status) -- nvim_command() failed.
+ eq('E492:', string.match(rv, 'E%d*:')) -- Vimscript error was returned.
+ eq('', api.nvim_eval('v:errmsg')) -- v:errmsg was not updated.
eq('', eval('v:exception'))
end)
it('Vimscript execution error: fails with specific error', function()
- local status, rv = pcall(nvim, "command", "buffer 23487")
- eq(false, status) -- nvim_command() failed.
- eq("E86: Buffer 23487 does not exist", string.match(rv, "E%d*:.*"))
- eq('', eval('v:errmsg')) -- v:errmsg was not updated.
+ local status, rv = pcall(command, 'buffer 23487')
+ eq(false, status) -- nvim_command() failed.
+ eq('E86: Buffer 23487 does not exist', string.match(rv, 'E%d*:.*'))
+ eq('', eval('v:errmsg')) -- v:errmsg was not updated.
eq('', eval('v:exception'))
end)
it('gives E493 instead of prompting on backwards range', function()
command('split')
- eq('Vim(windo):E493: Backwards range given: 2,1windo echo',
- pcall_err(command, '2,1windo echo'))
+ eq(
+ 'Vim(windo):E493: Backwards range given: 2,1windo echo',
+ pcall_err(command, '2,1windo echo')
+ )
end)
end)
describe('nvim_command_output', function()
it('does not induce hit-enter prompt', function()
- nvim("ui_attach", 80, 20, {})
+ api.nvim_ui_attach(80, 20, {})
-- Induce a hit-enter prompt use nvim_input (non-blocking).
- nvim('command', 'set cmdheight=1')
- nvim('input', [[:echo "hi\nhi2"<CR>]])
+ command('set cmdheight=1')
+ api.nvim_input([[:echo "hi\nhi2"<CR>]])
-- Verify hit-enter prompt.
- eq({mode='r', blocking=true}, nvim("get_mode"))
- nvim('input', [[<C-c>]])
+ eq({ mode = 'r', blocking = true }, api.nvim_get_mode())
+ api.nvim_input([[<C-c>]])
-- Verify NO hit-enter prompt.
- nvim('command_output', [[echo "hi\nhi2"]])
- eq({mode='n', blocking=false}, nvim("get_mode"))
+ command_output([[echo "hi\nhi2"]])
+ eq({ mode = 'n', blocking = false }, api.nvim_get_mode())
end)
it('captures command output', function()
- eq('this is\nspinal tap',
- nvim('command_output', [[echo "this is\nspinal tap"]]))
- eq('no line ending!',
- nvim('command_output', [[echon "no line ending!"]]))
+ eq('this is\nspinal tap', command_output([[echo "this is\nspinal tap"]]))
+ eq('no line ending!', command_output([[echon "no line ending!"]]))
end)
it('captures empty command output', function()
- eq('', nvim('command_output', 'echo'))
+ eq('', command_output('echo'))
end)
it('captures single-char command output', function()
- eq('x', nvim('command_output', 'echo "x"'))
+ eq('x', command_output('echo "x"'))
end)
it('captures multiple commands', function()
- eq('foo\n 1 %a "[No Name]" line 1',
- nvim('command_output', 'echo "foo" | ls'))
+ eq('foo\n 1 %a "[No Name]" line 1', command_output('echo "foo" | ls'))
end)
it('captures nested execute()', function()
- eq('\nnested1\nnested2\n 1 %a "[No Name]" line 1',
- nvim('command_output',
- [[echo execute('echo "nested1\nnested2"') | ls]]))
+ eq(
+ '\nnested1\nnested2\n 1 %a "[No Name]" line 1',
+ command_output([[echo execute('echo "nested1\nnested2"') | ls]])
+ )
end)
it('captures nested nvim_command_output()', function()
- eq('nested1\nnested2\n 1 %a "[No Name]" line 1',
- nvim('command_output',
- [[echo nvim_command_output('echo "nested1\nnested2"') | ls]]))
+ eq(
+ 'nested1\nnested2\n 1 %a "[No Name]" line 1',
+ command_output([[echo nvim_command_output('echo "nested1\nnested2"') | ls]])
+ )
end)
it('returns shell |:!| output', function()
local win_lf = is_os('win') and '\r' or ''
- eq(':!echo foo\r\n\nfoo'..win_lf..'\n', nvim('command_output', [[!echo foo]]))
+ eq(':!echo foo\r\n\nfoo' .. win_lf .. '\n', command_output([[!echo foo]]))
end)
it('Vimscript validation error: fails with specific error', function()
- local status, rv = pcall(nvim, "command_output", "bogus commannnd")
- eq(false, status) -- nvim_command_output() failed.
- eq("E492: Not an editor command: bogus commannnd",
- string.match(rv, "E%d*:.*"))
- eq('', eval('v:errmsg')) -- v:errmsg was not updated.
+ local status, rv = pcall(command_output, 'bogus commannnd')
+ eq(false, status) -- nvim_command_output() failed.
+ eq('E492: Not an editor command: bogus commannnd', string.match(rv, 'E%d*:.*'))
+ eq('', eval('v:errmsg')) -- v:errmsg was not updated.
-- Verify NO hit-enter prompt.
- eq({mode='n', blocking=false}, nvim("get_mode"))
+ eq({ mode = 'n', blocking = false }, api.nvim_get_mode())
end)
it('Vimscript execution error: fails with specific error', function()
- local status, rv = pcall(nvim, "command_output", "buffer 42")
- eq(false, status) -- nvim_command_output() failed.
- eq("E86: Buffer 42 does not exist", string.match(rv, "E%d*:.*"))
- eq('', eval('v:errmsg')) -- v:errmsg was not updated.
+ local status, rv = pcall(command_output, 'buffer 42')
+ eq(false, status) -- nvim_command_output() failed.
+ eq('E86: Buffer 42 does not exist', string.match(rv, 'E%d*:.*'))
+ eq('', eval('v:errmsg')) -- v:errmsg was not updated.
-- Verify NO hit-enter prompt.
- eq({mode='n', blocking=false}, nvim("get_mode"))
+ eq({ mode = 'n', blocking = false }, api.nvim_get_mode())
end)
it('does not cause heap buffer overflow with large output', function()
- eq(eval('string(range(1000000))'),
- nvim('command_output', 'echo range(1000000)'))
+ eq(eval('string(range(1000000))'), command_output('echo range(1000000)'))
end)
end)
describe('nvim_eval', function()
it('works', function()
- nvim('command', 'let g:v1 = "a"')
- nvim('command', 'let g:v2 = [1, 2, {"v3": 3}]')
- eq({v1 = 'a', v2 = { 1, 2, { v3 = 3 } } }, nvim('eval', 'g:'))
+ command('let g:v1 = "a"')
+ command('let g:v2 = [1, 2, {"v3": 3}]')
+ eq({ v1 = 'a', v2 = { 1, 2, { v3 = 3 } } }, api.nvim_eval('g:'))
end)
it('handles NULL-initialized strings correctly', function()
- eq(1, nvim('eval',"matcharg(1) == ['', '']"))
- eq({'', ''}, nvim('eval','matcharg(1)'))
+ eq(1, api.nvim_eval("matcharg(1) == ['', '']"))
+ eq({ '', '' }, api.nvim_eval('matcharg(1)'))
end)
it('works under deprecated name', function()
- eq(2, request("vim_eval", "1+1"))
+ eq(2, request('vim_eval', '1+1'))
end)
- it("Vimscript error: returns error details, does NOT update v:errmsg", function()
- eq('Vim:E121: Undefined variable: bogus',
- pcall_err(request, 'nvim_eval', 'bogus expression'))
- eq('', eval('v:errmsg')) -- v:errmsg was not updated.
+ it('Vimscript error: returns error details, does NOT update v:errmsg', function()
+ eq('Vim:E121: Undefined variable: bogus', pcall_err(request, 'nvim_eval', 'bogus expression'))
+ eq('', eval('v:errmsg')) -- v:errmsg was not updated.
end)
end)
describe('nvim_call_function', function()
it('works', function()
- nvim('call_function', 'setqflist', { { { filename = 'something', lnum = 17 } }, 'r' })
- eq(17, nvim('call_function', 'getqflist', {})[1].lnum)
- eq(17, nvim('call_function', 'eval', {17}))
- eq('foo', nvim('call_function', 'simplify', {'this/./is//redundant/../../../foo'}))
- end)
-
- it("Vimscript validation error: returns specific error, does NOT update v:errmsg", function()
- eq('Vim:E117: Unknown function: bogus function',
- pcall_err(request, 'nvim_call_function', 'bogus function', {'arg1'}))
- eq('Vim:E119: Not enough arguments for function: atan',
- pcall_err(request, 'nvim_call_function', 'atan', {}))
+ api.nvim_call_function('setqflist', { { { filename = 'something', lnum = 17 } }, 'r' })
+ eq(17, api.nvim_call_function('getqflist', {})[1].lnum)
+ eq(17, api.nvim_call_function('eval', { 17 }))
+ eq('foo', api.nvim_call_function('simplify', { 'this/./is//redundant/../../../foo' }))
+ end)
+
+ it('Vimscript validation error: returns specific error, does NOT update v:errmsg', function()
+ eq(
+ 'Vim:E117: Unknown function: bogus function',
+ pcall_err(request, 'nvim_call_function', 'bogus function', { 'arg1' })
+ )
+ eq(
+ 'Vim:E119: Not enough arguments for function: atan',
+ pcall_err(request, 'nvim_call_function', 'atan', {})
+ )
eq('', eval('v:exception'))
- eq('', eval('v:errmsg')) -- v:errmsg was not updated.
- end)
-
- it("Vimscript error: returns error details, does NOT update v:errmsg", function()
- eq('Vim:E808: Number or Float required',
- pcall_err(request, 'nvim_call_function', 'atan', {'foo'}))
- eq('Vim:Invalid channel stream "xxx"',
- pcall_err(request, 'nvim_call_function', 'chanclose', {999, 'xxx'}))
- eq('Vim:E900: Invalid channel id',
- pcall_err(request, 'nvim_call_function', 'chansend', {999, 'foo'}))
+ eq('', eval('v:errmsg')) -- v:errmsg was not updated.
+ end)
+
+ it('Vimscript error: returns error details, does NOT update v:errmsg', function()
+ eq(
+ 'Vim:E808: Number or Float required',
+ pcall_err(request, 'nvim_call_function', 'atan', { 'foo' })
+ )
+ eq(
+ 'Vim:Invalid channel stream "xxx"',
+ pcall_err(request, 'nvim_call_function', 'chanclose', { 999, 'xxx' })
+ )
+ eq(
+ 'Vim:E900: Invalid channel id',
+ pcall_err(request, 'nvim_call_function', 'chansend', { 999, 'foo' })
+ )
eq('', eval('v:exception'))
- eq('', eval('v:errmsg')) -- v:errmsg was not updated.
+ eq('', eval('v:errmsg')) -- v:errmsg was not updated.
end)
- it("Vimscript exception: returns exception details, does NOT update v:errmsg", function()
+ it('Vimscript exception: returns exception details, does NOT update v:errmsg', function()
source([[
function! Foo() abort
throw 'wtf'
@@ -504,10 +607,11 @@ describe('API', function()
]])
eq('function Foo, line 1: wtf', pcall_err(request, 'nvim_call_function', 'Foo', {}))
eq('', eval('v:exception'))
- eq('', eval('v:errmsg')) -- v:errmsg was not updated.
+ eq('', eval('v:errmsg')) -- v:errmsg was not updated.
end)
it('validation', function()
+ -- stylua: ignore
local too_many_args = { 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x' }
source([[
function! Foo(...) abort
@@ -515,8 +619,10 @@ describe('API', function()
endfunction
]])
-- E740
- eq('Function called with too many arguments',
- pcall_err(request, 'nvim_call_function', 'Foo', too_many_args))
+ eq(
+ 'Function called with too many arguments',
+ pcall_err(request, 'nvim_call_function', 'Foo', too_many_args)
+ )
end)
end)
@@ -535,40 +641,55 @@ describe('API', function()
]])
-- :help Dictionary-function
- eq('Hello, World!', nvim('call_dict_function', 'g:test_dict_fn', 'F', {'World'}))
+ eq('Hello, World!', api.nvim_call_dict_function('g:test_dict_fn', 'F', { 'World' }))
-- Funcref is sent as NIL over RPC.
- eq({ greeting = 'Hello', F = NIL }, nvim('get_var', 'test_dict_fn'))
+ eq({ greeting = 'Hello', F = NIL }, api.nvim_get_var('test_dict_fn'))
-- :help numbered-function
- eq('Hi, Moon ...', nvim('call_dict_function', 'g:test_dict_fn2', 'F2', {'Moon'}))
+ eq('Hi, Moon ...', api.nvim_call_dict_function('g:test_dict_fn2', 'F2', { 'Moon' }))
-- Funcref is sent as NIL over RPC.
- eq({ greeting = 'Hi', F2 = NIL }, nvim('get_var', 'test_dict_fn2'))
+ eq({ greeting = 'Hi', F2 = NIL }, api.nvim_get_var('test_dict_fn2'))
-- Function specified via RPC dict.
source('function! G() dict\n return "@".(self.result)."@"\nendfunction')
- eq('@it works@', nvim('call_dict_function', { result = 'it works', G = 'G'}, 'G', {}))
+ eq('@it works@', api.nvim_call_dict_function({ result = 'it works', G = 'G' }, 'G', {}))
end)
it('validation', function()
command('let g:d={"baz":"zub","meep":[]}')
- eq('Not found: bogus',
- pcall_err(request, 'nvim_call_dict_function', 'g:d', 'bogus', {1,2}))
- eq('Not a function: baz',
- pcall_err(request, 'nvim_call_dict_function', 'g:d', 'baz', {1,2}))
- eq('Not a function: meep',
- pcall_err(request, 'nvim_call_dict_function', 'g:d', 'meep', {1,2}))
- eq('Vim:E117: Unknown function: f',
- pcall_err(request, 'nvim_call_dict_function', { f = '' }, 'f', {1,2}))
- eq('Not a function: f',
- pcall_err(request, 'nvim_call_dict_function', "{ 'f': '' }", 'f', {1,2}))
- eq('dict argument type must be String or Dictionary',
- pcall_err(request, 'nvim_call_dict_function', 42, 'f', {1,2}))
- eq('Failed to evaluate dict expression',
- pcall_err(request, 'nvim_call_dict_function', 'foo', 'f', {1,2}))
- eq('dict not found',
- pcall_err(request, 'nvim_call_dict_function', '42', 'f', {1,2}))
- eq('Invalid (empty) function name',
- pcall_err(request, 'nvim_call_dict_function', "{ 'f': '' }", '', {1,2}))
+ eq(
+ 'Not found: bogus',
+ pcall_err(request, 'nvim_call_dict_function', 'g:d', 'bogus', { 1, 2 })
+ )
+ eq(
+ 'Not a function: baz',
+ pcall_err(request, 'nvim_call_dict_function', 'g:d', 'baz', { 1, 2 })
+ )
+ eq(
+ 'Not a function: meep',
+ pcall_err(request, 'nvim_call_dict_function', 'g:d', 'meep', { 1, 2 })
+ )
+ eq(
+ 'Vim:E117: Unknown function: f',
+ pcall_err(request, 'nvim_call_dict_function', { f = '' }, 'f', { 1, 2 })
+ )
+ eq(
+ 'Not a function: f',
+ pcall_err(request, 'nvim_call_dict_function', "{ 'f': '' }", 'f', { 1, 2 })
+ )
+ eq(
+ 'dict argument type must be String or Dictionary',
+ pcall_err(request, 'nvim_call_dict_function', 42, 'f', { 1, 2 })
+ )
+ eq(
+ 'Failed to evaluate dict expression',
+ pcall_err(request, 'nvim_call_dict_function', 'foo', 'f', { 1, 2 })
+ )
+ eq('dict not found', pcall_err(request, 'nvim_call_dict_function', '42', 'f', { 1, 2 }))
+ eq(
+ 'Invalid (empty) function name',
+ pcall_err(request, 'nvim_call_dict_function', "{ 'f': '' }", '', { 1, 2 })
+ )
end)
end)
@@ -576,85 +697,95 @@ describe('API', function()
local start_dir
before_each(function()
- funcs.mkdir("Xtestdir")
- start_dir = funcs.getcwd()
+ fn.mkdir('Xtestdir')
+ start_dir = fn.getcwd()
end)
after_each(function()
- helpers.rmdir("Xtestdir")
+ helpers.rmdir('Xtestdir')
end)
it('works', function()
- meths.set_current_dir("Xtestdir")
- eq(funcs.getcwd(), start_dir .. helpers.get_pathsep() .. "Xtestdir")
+ api.nvim_set_current_dir('Xtestdir')
+ eq(fn.getcwd(), start_dir .. helpers.get_pathsep() .. 'Xtestdir')
end)
it('sets previous directory', function()
- meths.set_current_dir("Xtestdir")
+ api.nvim_set_current_dir('Xtestdir')
command('cd -')
- eq(funcs.getcwd(), start_dir)
+ eq(fn.getcwd(), start_dir)
end)
end)
describe('nvim_exec_lua', function()
it('works', function()
- meths.exec_lua('vim.api.nvim_set_var("test", 3)', {})
- eq(3, meths.get_var('test'))
+ api.nvim_exec_lua('vim.api.nvim_set_var("test", 3)', {})
+ eq(3, api.nvim_get_var('test'))
- eq(17, meths.exec_lua('a, b = ...\nreturn a + b', {10,7}))
+ eq(17, api.nvim_exec_lua('a, b = ...\nreturn a + b', { 10, 7 }))
- eq(NIL, meths.exec_lua('function xx(a,b)\nreturn a..b\nend',{}))
- eq("xy", meths.exec_lua('return xx(...)', {'x','y'}))
+ eq(NIL, api.nvim_exec_lua('function xx(a,b)\nreturn a..b\nend', {}))