diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2023-11-30 20:35:25 +0000 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2023-11-30 20:35:25 +0000 |
commit | 1b7b916b7631ddf73c38e3a0070d64e4636cb2f3 (patch) | |
tree | cd08258054db80bb9a11b1061bb091c70b76926a /test/functional/lua/vim_spec.lua | |
parent | eaa89c11d0f8aefbb512de769c6c82f61a8baca3 (diff) | |
parent | 4a8bf24ac690004aedf5540fa440e788459e5e34 (diff) | |
download | rneovim-aucmd_textputpost.tar.gz rneovim-aucmd_textputpost.tar.bz2 rneovim-aucmd_textputpost.zip |
Merge remote-tracking branch 'upstream/master' into aucmd_textputpostaucmd_textputpost
Diffstat (limited to 'test/functional/lua/vim_spec.lua')
-rw-r--r-- | test/functional/lua/vim_spec.lua | 487 |
1 files changed, 388 insertions, 99 deletions
diff --git a/test/functional/lua/vim_spec.lua b/test/functional/lua/vim_spec.lua index 867f366d06..ebe5fc254e 100644 --- a/test/functional/lua/vim_spec.lua +++ b/test/functional/lua/vim_spec.lua @@ -6,10 +6,12 @@ local nvim_prog = helpers.nvim_prog local funcs = helpers.funcs local meths = helpers.meths local command = helpers.command +local dedent = helpers.dedent local insert = helpers.insert local clear = helpers.clear local eq = helpers.eq local ok = helpers.ok +local pesc = helpers.pesc local eval = helpers.eval local feed = helpers.feed local pcall_err = helpers.pcall_err @@ -126,6 +128,22 @@ describe('lua stdlib', function() eq(1, funcs.luaeval('vim.stricmp("\\0C\\0", "\\0B\\0")')) end) + it('vim.deprecate', function() + -- vim.deprecate(name, alternative, version, plugin, backtrace) + eq(dedent[[ + foo.bar() is deprecated, use zub.wooo{ok=yay} instead. :help deprecated + This feature will be removed in Nvim version 2.17]], + exec_lua('return vim.deprecate(...)', 'foo.bar()', 'zub.wooo{ok=yay}', '2.17')) + -- Same message, skipped. + eq(vim.NIL, + exec_lua('return vim.deprecate(...)', 'foo.bar()', 'zub.wooo{ok=yay}', '2.17')) + -- When `plugin` is specified, don't show ":help deprecated". #22235 + eq(dedent[[ + foo.bar() is deprecated, use zub.wooo{ok=yay} instead. + This feature will be removed in my-plugin.nvim version 0.3.0]], + exec_lua('return vim.deprecate(...)', 'foo.bar()', 'zub.wooo{ok=yay}', '0.3.0', 'my-plugin.nvim', false)) + end) + it('vim.startswith', function() eq(true, funcs.luaeval('vim.startswith("123", "1")')) eq(true, funcs.luaeval('vim.startswith("123", "")')) @@ -259,7 +277,7 @@ describe('lua stdlib', function() | ]]} - -- nvim_command causes a vimL exception, check that it is properly caught + -- nvim_command causes a Vimscript exception, check that it is properly caught -- and propagated as an error message in async contexts.. #10809 exec_lua([[ vim.schedule(function() @@ -275,51 +293,53 @@ describe('lua stdlib', function() ]]} end) - it("vim.split", function() - local split = function(str, sep, kwargs) - return exec_lua('return vim.split(...)', str, sep, kwargs) - end - + it('vim.gsplit, vim.split', function() local tests = { - { "a,b", ",", false, false, { 'a', 'b' } }, - { ":aa::bb:", ":", false, false, { '', 'aa', '', 'bb', '' } }, - { ":aa::bb:", ":", false, true, { 'aa', '', 'bb' } }, - { "::ee::ff:", ":", false, false, { '', '', 'ee', '', 'ff', '' } }, - { "::ee::ff:", ":", false, true, { 'ee', '', 'ff' } }, - { "ab", ".", false, false, { '', '', '' } }, - { "a1b2c", "[0-9]", false, false, { 'a', 'b', 'c' } }, - { "xy", "", false, false, { 'x', 'y' } }, - { "here be dragons", " ", false, false, { "here", "be", "dragons"} }, - { "axaby", "ab?", false, false, { '', 'x', 'y' } }, - { "f v2v v3v w2w ", "([vw])2%1", false, false, { 'f ', ' v3v ', ' ' } }, - { "", "", false, false, {} }, - { "", "a", false, false, { '' } }, - { "x*yz*oo*l", "*", true, false, { 'x', 'yz', 'oo', 'l' } }, + -- plain trimempty + { 'a,b', ',', false, false, { 'a', 'b' } }, + { ':aa::::bb:', ':', false, false, { '', 'aa', '', '', '', 'bb', '' } }, + { ':aa::::bb:', ':', false, true, { 'aa', '', '', '', 'bb' } }, + { 'aa::::bb:', ':', false, true, { 'aa', '', '', '', 'bb' } }, + { ':aa::bb:', ':', false, true, { 'aa', '', 'bb' } }, + { '/a/b:/b/\n', '[:\n]', false, true, { '/a/b', '/b/' } }, + { '::ee::ff:', ':', false, false, { '', '', 'ee', '', 'ff', '' } }, + { '::ee::ff::', ':', false, true, { 'ee', '', 'ff' } }, + { 'ab', '.', false, false, { '', '', '' } }, + { 'a1b2c', '[0-9]', false, false, { 'a', 'b', 'c' } }, + { 'xy', '', false, false, { 'x', 'y' } }, + { 'here be dragons', ' ', false, false, { 'here', 'be', 'dragons'} }, + { 'axaby', 'ab?', false, false, { '', 'x', 'y' } }, + { 'f v2v v3v w2w ', '([vw])2%1', false, false, { 'f ', ' v3v ', ' ' } }, + { '', '', false, false, {} }, + { '', '', false, true, {} }, + { '\n', '[:\n]', false, true, {} }, + { '', 'a', false, false, { '' } }, + { 'x*yz*oo*l', '*', true, false, { 'x', 'yz', 'oo', 'l' } }, } for _, t in ipairs(tests) do - eq(t[5], split(t[1], t[2], {plain=t[3], trimempty=t[4]})) + eq(t[5], vim.split(t[1], t[2], {plain=t[3], trimempty=t[4]}), t[1]) end -- Test old signature - eq({'x', 'yz', 'oo', 'l'}, split("x*yz*oo*l", "*", true)) + eq({'x', 'yz', 'oo', 'l'}, vim.split("x*yz*oo*l", "*", true)) local loops = { { "abc", ".-" }, } for _, t in ipairs(loops) do - matches("Infinite loop detected", pcall_err(split, t[1], t[2])) + matches("Infinite loop detected", pcall_err(vim.split, t[1], t[2])) end -- Validates args. - eq(true, pcall(split, 'string', 'string')) + eq(true, pcall(vim.split, 'string', 'string')) matches('s: expected string, got number', - pcall_err(split, 1, 'string')) + pcall_err(vim.split, 1, 'string')) matches('sep: expected string, got number', - pcall_err(split, 'string', 1)) - matches('kwargs: expected table, got number', - pcall_err(split, 'string', 'string', 1)) + pcall_err(vim.split, 'string', 1)) + matches('opts: expected table, got number', + pcall_err(vim.split, 'string', 'string', 1)) end) it('vim.trim', function() @@ -444,6 +464,22 @@ describe('lua stdlib', function() pcall_err(exec_lua, [[return vim.pesc(2)]])) end) + it('vim.list_contains', function() + eq(true, exec_lua("return vim.list_contains({'a','b','c'}, 'c')")) + eq(false, exec_lua("return vim.list_contains({'a','b','c'}, 'd')")) + end) + + it('vim.tbl_contains', function() + eq(true, exec_lua("return vim.tbl_contains({'a','b','c'}, 'c')")) + eq(false, exec_lua("return vim.tbl_contains({'a','b','c'}, 'd')")) + eq(true, exec_lua("return vim.tbl_contains({[2]='a',foo='b',[5] = 'c'}, 'c')")) + eq(true, exec_lua([[ + return vim.tbl_contains({ 'a', { 'b', 'c' } }, function(v) + return vim.deep_equal(v, { 'b', 'c' }) + end, { predicate = true }) + ]])) + end) + it('vim.tbl_keys', function() eq({}, exec_lua("return vim.tbl_keys({})")) for _, v in pairs(exec_lua("return vim.tbl_keys({'a', 'b', 'c'})")) do @@ -488,6 +524,19 @@ describe('lua stdlib', function() ]])) end) + it('vim.tbl_isarray', function() + eq(true, exec_lua("return vim.tbl_isarray({})")) + eq(false, exec_lua("return vim.tbl_isarray(vim.empty_dict())")) + eq(true, exec_lua("return vim.tbl_isarray({'a', 'b', 'c'})")) + eq(false, exec_lua("return vim.tbl_isarray({'a', '32', a='hello', b='baz'})")) + eq(false, exec_lua("return vim.tbl_isarray({1, a='hello', b='baz'})")) + eq(false, exec_lua("return vim.tbl_isarray({a='hello', b='baz', 1})")) + eq(false, exec_lua("return vim.tbl_isarray({1, 2, nil, a='hello'})")) + eq(true, exec_lua("return vim.tbl_isarray({1, 2, nil, 4})")) + eq(true, exec_lua("return vim.tbl_isarray({nil, 2, 3, 4})")) + eq(false, exec_lua("return vim.tbl_isarray({1, [1.5]=2, [3]=3})")) + end) + it('vim.tbl_islist', function() eq(true, exec_lua("return vim.tbl_islist({})")) eq(false, exec_lua("return vim.tbl_islist(vim.empty_dict())")) @@ -496,6 +545,9 @@ describe('lua stdlib', function() eq(false, exec_lua("return vim.tbl_islist({1, a='hello', b='baz'})")) eq(false, exec_lua("return vim.tbl_islist({a='hello', b='baz', 1})")) eq(false, exec_lua("return vim.tbl_islist({1, 2, nil, a='hello'})")) + eq(false, exec_lua("return vim.tbl_islist({1, 2, nil, 4})")) + eq(false, exec_lua("return vim.tbl_islist({nil, 2, 3, 4})")) + eq(false, exec_lua("return vim.tbl_islist({1, [1.5]=2, [3]=3})")) end) it('vim.tbl_isempty', function() @@ -780,7 +832,7 @@ describe('lua stdlib', function() it('vim.call, vim.fn', function() eq(true, exec_lua([[return vim.call('sin', 0.0) == 0.0 ]])) eq(true, exec_lua([[return vim.fn.sin(0.0) == 0.0 ]])) - -- compat: nvim_call_function uses "special" value for vimL float + -- compat: nvim_call_function uses "special" value for Vimscript float eq(false, exec_lua([[return vim.api.nvim_call_function('sin', {0.0}) == 0.0 ]])) exec([[ @@ -831,7 +883,7 @@ describe('lua stdlib', function() it('vim.fn is allowed in "fast" context by some functions #18306', function() exec_lua([[ - local timer = vim.loop.new_timer() + local timer = vim.uv.new_timer() timer:start(0, 0, function() timer:close() assert(vim.in_fast_event()) @@ -897,7 +949,7 @@ describe('lua stdlib', function() }) screen:attach() exec_lua([[ - timer = vim.loop.new_timer() + timer = vim.uv.new_timer() timer:start(20, 0, function () -- notify ok (executed later when safe) vim.rpcnotify(chan, 'nvim_set_var', 'yy', {3, vim.NIL}) @@ -1440,14 +1492,68 @@ describe('lua stdlib', function() eq(NIL, funcs.luaeval "vim.v.null") matches([[attempt to index .* nil value]], pcall_err(exec_lua, 'return vim.v[0].progpath')) + eq('Key is read-only: count', pcall_err(exec_lua, [[vim.v.count = 42]])) + eq('Dictionary is locked', pcall_err(exec_lua, [[vim.v.nosuchvar = 42]])) + eq('Key is fixed: errmsg', pcall_err(exec_lua, [[vim.v.errmsg = nil]])) + exec_lua([[vim.v.errmsg = 'set by Lua']]) + eq('set by Lua', eval('v:errmsg')) + exec_lua([[vim.v.errmsg = 42]]) + eq('42', eval('v:errmsg')) + exec_lua([[vim.v.oldfiles = { 'one', 'two' }]]) + eq({ 'one', 'two' }, eval('v:oldfiles')) + exec_lua([[vim.v.oldfiles = {}]]) + eq({}, eval('v:oldfiles')) + eq('Setting v:oldfiles to value with wrong type', pcall_err(exec_lua, [[vim.v.oldfiles = 'a']])) + eq({}, eval('v:oldfiles')) + + feed('i foo foo foo<Esc>0/foo<CR>') + eq({1, 1}, meths.win_get_cursor(0)) + eq(1, eval('v:searchforward')) + feed('n') + eq({1, 5}, meths.win_get_cursor(0)) + exec_lua([[vim.v.searchforward = 0]]) + eq(0, eval('v:searchforward')) + feed('n') + eq({1, 1}, meths.win_get_cursor(0)) + exec_lua([[vim.v.searchforward = 1]]) + eq(1, eval('v:searchforward')) + feed('n') + eq({1, 5}, meths.win_get_cursor(0)) + + local screen = Screen.new(60, 3) + screen:set_default_attr_ids({ + [0] = {bold = true, foreground = Screen.colors.Blue}, + [1] = {background = Screen.colors.Yellow}, + }) + screen:attach() + eq(1, eval('v:hlsearch')) + screen:expect{grid=[[ + {1:foo} {1:^foo} {1:foo} | + {0:~ }| + | + ]]} + exec_lua([[vim.v.hlsearch = 0]]) + eq(0, eval('v:hlsearch')) + screen:expect{grid=[[ + foo ^foo foo | + {0:~ }| + | + ]]} + exec_lua([[vim.v.hlsearch = 1]]) + eq(1, eval('v:hlsearch')) + screen:expect{grid=[[ + {1:foo} {1:^foo} {1:foo} | + {0:~ }| + | + ]]} end) it('vim.bo', function() eq('', funcs.luaeval "vim.bo.filetype") exec_lua [[ - vim.api.nvim_buf_set_option(0, "filetype", "markdown") + vim.api.nvim_set_option_value("filetype", "markdown", {}) BUF = vim.api.nvim_create_buf(false, true) - vim.api.nvim_buf_set_option(BUF, "modifiable", false) + vim.api.nvim_set_option_value("modifiable", false, {buf = BUF}) ]] eq(false, funcs.luaeval "vim.bo.modified") eq('markdown', funcs.luaeval "vim.bo.filetype") @@ -1458,9 +1564,9 @@ describe('lua stdlib', function() ]] eq('', funcs.luaeval "vim.bo.filetype") eq(true, funcs.luaeval "vim.bo[BUF].modifiable") - matches("no such option: 'nosuchopt'$", + matches("Unknown option 'nosuchopt'$", pcall_err(exec_lua, 'return vim.bo.nosuchopt')) - matches("Expected lua string$", + matches("Expected Lua string$", pcall_err(exec_lua, 'return vim.bo[0][0].autoread')) matches("Invalid buffer id: %-1$", pcall_err(exec_lua, 'return vim.bo[-1].filetype')) @@ -1468,9 +1574,9 @@ describe('lua stdlib', function() it('vim.wo', function() exec_lua [[ - vim.api.nvim_win_set_option(0, "cole", 2) + vim.api.nvim_set_option_value("cole", 2, {}) vim.cmd "split" - vim.api.nvim_win_set_option(0, "cole", 2) + vim.api.nvim_set_option_value("cole", 2, {}) ]] eq(2, funcs.luaeval "vim.wo.cole") exec_lua [[ @@ -1479,10 +1585,8 @@ describe('lua stdlib', function() eq(0, funcs.luaeval "vim.wo.cole") eq(0, funcs.luaeval "vim.wo[0].cole") eq(0, funcs.luaeval "vim.wo[1001].cole") - matches("no such option: 'notanopt'$", + matches("Unknown option 'notanopt'$", pcall_err(exec_lua, 'return vim.wo.notanopt')) - matches("Expected lua string$", - pcall_err(exec_lua, 'return vim.wo[0][0].list')) matches("Invalid window id: %-1$", pcall_err(exec_lua, 'return vim.wo[-1].list')) eq(2, funcs.luaeval "vim.wo[1000].cole") @@ -1497,6 +1601,11 @@ describe('lua stdlib', function() eq(200, funcs.luaeval "vim.wo.scrolloff") exec_lua [[vim.wo.scrolloff = -1]] eq(100, funcs.luaeval "vim.wo.scrolloff") + exec_lua [[ + vim.wo[0][0].scrolloff = 200 + vim.cmd "enew" + ]] + eq(100, funcs.luaeval "vim.wo.scrolloff") end) describe('vim.opt', function() @@ -1515,8 +1624,8 @@ describe('lua stdlib', function() local result = exec_lua [[ local result = {} - table.insert(result, vim.api.nvim_get_option('scrolloff')) - table.insert(result, vim.api.nvim_win_get_option(0, 'scrolloff')) + table.insert(result, vim.api.nvim_get_option_value('scrolloff', {scope='global'})) + table.insert(result, vim.api.nvim_get_option_value('scrolloff', {win=0})) return result ]] @@ -1580,20 +1689,20 @@ describe('lua stdlib', function() local result = {} vim.opt.makeprg = "global-local" - table.insert(result, vim.api.nvim_get_option('makeprg')) - table.insert(result, vim.api.nvim_buf_get_option(0, 'makeprg')) + table.insert(result, vim.go.makeprg) + table.insert(result, vim.api.nvim_get_option_value('makeprg', {buf=0})) vim.opt_local.mp = "only-local" - table.insert(result, vim.api.nvim_get_option('makeprg')) - table.insert(result, vim.api.nvim_buf_get_option(0, 'makeprg')) + table.insert(result, vim.go.makeprg) + table.insert(result, vim.api.nvim_get_option_value('makeprg', {buf=0})) vim.opt_global.makeprg = "only-global" - table.insert(result, vim.api.nvim_get_option('makeprg')) - table.insert(result, vim.api.nvim_buf_get_option(0, 'makeprg')) + table.insert(result, vim.go.makeprg) + table.insert(result, vim.api.nvim_get_option_value('makeprg', {buf=0})) vim.opt.makeprg = "global-local" - table.insert(result, vim.api.nvim_get_option('makeprg')) - table.insert(result, vim.api.nvim_buf_get_option(0, 'makeprg')) + table.insert(result, vim.go.makeprg) + table.insert(result, vim.api.nvim_get_option_value('makeprg', {buf=0})) return result ]] @@ -2122,7 +2231,7 @@ describe('lua stdlib', function() it('can handle isfname ,,,', function() local result = exec_lua [[ vim.opt.isfname = "a,b,,,c" - return { vim.opt.isfname:get(), vim.api.nvim_get_option('isfname') } + return { vim.opt.isfname:get(), vim.go.isfname } ]] eq({{",", "a", "b", "c"}, "a,b,,,c"}, result) @@ -2132,7 +2241,7 @@ describe('lua stdlib', function() it('can handle isfname ,^,,', function() local result = exec_lua [[ vim.opt.isfname = "a,b,^,,c" - return { vim.opt.isfname:get(), vim.api.nvim_get_option('isfname') } + return { vim.opt.isfname:get(), vim.go.isfname } ]] eq({{"^,", "a", "b", "c"}, "a,b,^,,c"}, result) @@ -2203,8 +2312,8 @@ describe('lua stdlib', function() end) end) -- vim.opt - describe('opt_local', function() - it('should be able to append to an array list type option', function() + describe('vim.opt_local', function() + it('appends into global value when changing local option value', function() eq({ "foo,bar,baz,qux" }, exec_lua [[ local result = {} @@ -2219,6 +2328,19 @@ describe('lua stdlib', function() end) end) + describe('vim.opt_global', function() + it('gets current global option value', function() + eq({ "yes" }, exec_lua [[ + local result = {} + + vim.cmd "setglobal signcolumn=yes" + table.insert(result, vim.opt_global.signcolumn:get()) + + return result + ]]) + end) + end) + it('vim.cmd', function() exec_lua [[ vim.cmd "autocmd BufNew * ++once lua BUF = vim.fn.expand('<abuf>')" @@ -2269,17 +2391,36 @@ describe('lua stdlib', function() describe('vim.region', function() it('charwise', function() - insert(helpers.dedent( [[ + insert(dedent( [[ text tααt tααt text text tαxt txtα tex text tαxt tαxt ]])) - eq({5,15}, exec_lua[[ return vim.region(0,{1,5},{1,14},'v',true)[1] ]]) + eq({5,13}, exec_lua[[ return vim.region(0,{0,5},{0,13},'v',false)[0] ]]) + eq({5,15}, exec_lua[[ return vim.region(0,{0,5},{0,13},'v',true)[0] ]]) + eq({5,15}, exec_lua[[ return vim.region(0,{0,5},{0,14},'v',true)[0] ]]) + eq({5,15}, exec_lua[[ return vim.region(0,{0,5},{0,15},'v',false)[0] ]]) + eq({5,17}, exec_lua[[ return vim.region(0,{0,5},{0,15},'v',true)[0] ]]) + eq({5,17}, exec_lua[[ return vim.region(0,{0,5},{0,16},'v',true)[0] ]]) + eq({5,17}, exec_lua[[ return vim.region(0,{0,5},{0,17},'v',false)[0] ]]) + eq({5,18}, exec_lua[[ return vim.region(0,{0,5},{0,17},'v',true)[0] ]]) end) it('blockwise', function() insert([[αα]]) eq({0,5}, exec_lua[[ return vim.region(0,{0,0},{0,4},'3',true)[0] ]]) end) + it('linewise', function() + insert(dedent( [[ + text tααt tααt text + text tαxt txtα tex + text tαxt tαxt + ]])) + eq({0,-1}, exec_lua[[ return vim.region(0,{1,5},{1,14},'V',true)[1] ]]) + end) + it('getpos() input', function() + insert('getpos') + eq({0,6}, exec_lua[[ return vim.region(0,{0,0},'.','v',true)[0] ]]) + end) end) describe('vim.on_key', function() @@ -2305,6 +2446,12 @@ describe('lua stdlib', function() end) it('allows removing on_key listeners', function() + -- Create some unused namespaces + meths.create_namespace('unused1') + meths.create_namespace('unused2') + meths.create_namespace('unused3') + meths.create_namespace('unused4') + insert([[hello world]]) exec_lua [[ @@ -2420,13 +2567,12 @@ describe('lua stdlib', function() ]]) end) - it('should not block other events', function() eq({time = true, wait_result = true}, exec_lua[[ start_time = get_time() vim.g.timer_result = false - timer = vim.loop.new_timer() + timer = vim.uv.new_timer() timer:start(100, 0, vim.schedule_wrap(function() vim.g.timer_result = true end)) @@ -2448,7 +2594,7 @@ describe('lua stdlib', function() start_time = get_time() vim.g.timer_result = false - timer = vim.loop.new_timer() + timer = vim.uv.new_timer() timer:start(100, 0, vim.schedule_wrap(function() vim.g.timer_result = true end)) @@ -2462,6 +2608,7 @@ describe('lua stdlib', function() } ]]) end) + it('should work with vim.defer_fn', function() eq({time = true, wait_result = true}, exec_lua[[ start_time = get_time() @@ -2491,17 +2638,17 @@ describe('lua stdlib', function() it('should allow waiting with no callback, explicit', function() eq(true, exec_lua [[ - local start_time = vim.loop.hrtime() + local start_time = vim.uv.hrtime() vim.wait(50, nil) - return vim.loop.hrtime() - start_time > 25000 + return vim.uv.hrtime() - start_time > 25000 ]]) end) it('should allow waiting with no callback, implicit', function() eq(true, exec_lua [[ - local start_time = vim.loop.hrtime() + local start_time = vim.uv.hrtime() vim.wait(50) - return vim.loop.hrtime() - start_time > 25000 + return vim.uv.hrtime() - start_time > 25000 ]]) end) @@ -2623,6 +2770,23 @@ describe('lua stdlib', function() eq({'notification', 'wait', {-2}}, next_msg(500)) end) end) + + it('should not run in fast callbacks #26122', function() + local screen = Screen.new(80, 10) + screen:attach() + exec_lua([[ + local timer = vim.uv.new_timer() + timer:start(0, 0, function() + timer:close() + vim.wait(100, function() end) + end) + ]]) + screen:expect({ + any = pesc('E5560: vim.wait must not be called in a lua loop callback'), + }) + feed('<CR>') + assert_alive() + end) end) it('vim.notify_once', function() @@ -2679,14 +2843,14 @@ describe('lua stdlib', function() describe('vim.api.nvim_buf_call', function() it('can access buf options', function() - local buf1 = meths.get_current_buf() + local buf1 = meths.get_current_buf().id local buf2 = exec_lua [[ buf2 = vim.api.nvim_create_buf(false, true) return buf2 ]] - eq(false, meths.buf_get_option(buf1, 'autoindent')) - eq(false, meths.buf_get_option(buf2, 'autoindent')) + eq(false, meths.get_option_value('autoindent', {buf=buf1})) + eq(false, meths.get_option_value('autoindent', {buf=buf2})) local val = exec_lua [[ return vim.api.nvim_buf_call(buf2, function() @@ -2695,20 +2859,20 @@ describe('lua stdlib', function() end) ]] - eq(false, meths.buf_get_option(buf1, 'autoindent')) - eq(true, meths.buf_get_option(buf2, 'autoindent')) - eq(buf1, meths.get_current_buf()) + eq(false, meths.get_option_value('autoindent', {buf=buf1})) + eq(true, meths.get_option_value('autoindent', {buf=buf2})) + eq(buf1, meths.get_current_buf().id) eq(buf2, val) end) it('does not cause ml_get errors with invalid visual selection', function() -- Should be fixed by vim-patch:8.2.4028. exec_lua [[ - local a = vim.api - local t = function(s) return a.nvim_replace_termcodes(s, true, true, true) end - a.nvim_buf_set_lines(0, 0, -1, true, {"a", "b", "c"}) - a.nvim_feedkeys(t "G<C-V>", "txn", false) - a.nvim_buf_call(a.nvim_create_buf(false, true), function() vim.cmd "redraw" end) + local api = vim.api + local t = function(s) return api.nvim_replace_termcodes(s, true, true, true) end + api.nvim_buf_set_lines(0, 0, -1, true, {"a", "b", "c"}) + api.nvim_feedkeys(t "G<C-V>", "txn", false) + api.nvim_buf_call(api.nvim_create_buf(false, true), function() vim.cmd "redraw" end) ]] end) @@ -2716,10 +2880,10 @@ describe('lua stdlib', function() eq(true, exec_lua([[ local function scratch_buf_call(fn) local buf = vim.api.nvim_create_buf(false, true) - vim.api.nvim_buf_set_option(buf, 'cindent', true) + vim.api.nvim_set_option_value('cindent', true, {buf = buf}) return vim.api.nvim_buf_call(buf, function() return vim.api.nvim_get_current_buf() == buf - and vim.api.nvim_buf_get_option(buf, 'cindent') + and vim.api.nvim_get_option_value('cindent', {buf = buf}) and fn() end) and vim.api.nvim_buf_delete(buf, {}) == nil end @@ -2756,7 +2920,7 @@ describe('lua stdlib', function() describe('vim.api.nvim_win_call', function() it('can access window options', function() command('vsplit') - local win1 = meths.get_current_win() + local win1 = meths.get_current_win().id command('wincmd w') local win2 = exec_lua [[ win2 = vim.api.nvim_get_current_win() @@ -2764,8 +2928,8 @@ describe('lua stdlib', function() ]] command('wincmd p') - eq('', meths.win_get_option(win1, 'winhighlight')) - eq('', meths.win_get_option(win2, 'winhighlight')) + eq('', meths.get_option_value('winhighlight', {win=win1})) + eq('', meths.get_option_value('winhighlight', {win=win2})) local val = exec_lua [[ return vim.api.nvim_win_call(win2, function() @@ -2774,38 +2938,38 @@ describe('lua stdlib', function() end) ]] - eq('', meths.win_get_option(win1, 'winhighlight')) - eq('Normal:Normal', meths.win_get_option(win2, 'winhighlight')) - eq(win1, meths.get_current_win()) + eq('', meths.get_option_value('winhighlight', {win=win1})) + eq('Normal:Normal', meths.get_option_value('winhighlight', {win=win2})) + eq(win1, meths.get_current_win().id) eq(win2, val) end) it('does not cause ml_get errors with invalid visual selection', function() -- Add lines to the current buffer and make another window looking into an empty buffer. exec_lua [[ - _G.a = vim.api - _G.t = function(s) return a.nvim_replace_termcodes(s, true, true, true) end - _G.win_lines = a.nvim_get_current_win() + _G.api = vim.api + _G.t = function(s) return api.nvim_replace_termcodes(s, true, true, true) end + _G.win_lines = api.nvim_get_current_win() vim.cmd "new" - _G.win_empty = a.nvim_get_current_win() - a.nvim_set_current_win(win_lines) - a.nvim_buf_set_lines(0, 0, -1, true, {"a", "b", "c"}) + _G.win_empty = api.nvim_get_current_win() + api.nvim_set_current_win(win_lines) + api.nvim_buf_set_lines(0, 0, -1, true, {"a", "b", "c"}) ]] -- Start Visual in current window, redraw in other window with fewer lines. -- Should be fixed by vim-patch:8.2.4018. exec_lua [[ - a.nvim_feedkeys(t "G<C-V>", "txn", false) - a.nvim_win_call(win_empty, function() vim.cmd "redraw" end) + api.nvim_feedkeys(t "G<C-V>", "txn", false) + api.nvim_win_call(win_empty, function() vim.cmd "redraw" end) ]] -- Start Visual in current window, extend it in other window with more lines. -- Fixed for win_execute by vim-patch:8.2.4026, but nvim_win_call should also not be affected. exec_lua [[ - a.nvim_feedkeys(t "<Esc>gg", "txn", false) - a.nvim_set_current_win(win_empty) - a.nvim_feedkeys(t "gg<C-V>", "txn", false) - a.nvim_win_call(win_lines, function() a.nvim_feedkeys(t "G<C-V>", "txn", false) end) + api.nvim_feedkeys(t "<Esc>gg", "txn", false) + api.nvim_set_current_win(win_empty) + api.nvim_feedkeys(t "gg<C-V>", "txn", false) + api.nvim_win_call(win_lines, function() api.nvim_feedkeys(t "G<C-V>", "txn", false) end) vim.cmd "redraw" ]] end) @@ -2819,14 +2983,14 @@ describe('lua stdlib', function() } screen:attach() exec_lua [[ - _G.a = vim.api + _G.api = vim.api vim.opt.ruler = true local lines = {} for i = 0, 499 do lines[#lines + 1] = tostring(i) end - a.nvim_buf_set_lines(0, 0, -1, true, lines) - a.nvim_win_set_cursor(0, {20, 0}) + api.nvim_buf_set_lines(0, 0, -1, true, lines) + api.nvim_win_set_cursor(0, {20, 0}) vim.cmd "split" - _G.win = a.nvim_get_current_win() + _G.win = api.nvim_get_current_win() vim.cmd "wincmd w | redraw" ]] screen:expect [[ @@ -2837,7 +3001,7 @@ describe('lua stdlib', function() | ]] exec_lua [[ - a.nvim_win_call(win, function() a.nvim_win_set_cursor(0, {100, 0}) end) + api.nvim_win_call(win, function() api.nvim_win_set_cursor(0, {100, 0}) end) vim.cmd "redraw" ]] screen:expect [[ @@ -2898,8 +3062,133 @@ describe('lua stdlib', function() return a ]]) end) + + it('accepts the key name', function() + eq({ b = 'b', c = 'c' }, exec_lua [[ + local a = vim.defaulttable(function(k) return k end) + local _ = a.b + local _ = a.c + return a + ]]) + end) end) + it('vim.lua_omnifunc', function() + local screen = Screen.new(60,5) + screen:set_default_attr_ids { + [1] = {foreground = Screen.colors.Blue1, bold = true}; + [2] = {background = Screen.colors.WebGray}; + [3] = {background = Screen.colors.LightMagenta}; + [4] = {bold = true}; + [5] = {foreground = Screen.colors.SeaGreen, bold = true}; + } + screen:attach() + command [[ set omnifunc=v:lua.vim.lua_omnifunc ]] + + -- Note: the implementation is shared with lua command line completion. + -- More tests for completion in lua/command_line_completion_spec.lua + feed [[ivim.insp<c-x><c-o>]] + screen:expect{grid=[[ + vim.inspect^ | + {1:~ }{2: inspect }{1: }| + {1:~ }{3: inspect_pos }{1: }| + {1:~ }| + {4:-- Omni completion (^O^N^P) }{5:match 1 of 2} | + ]]} + end) + + it('vim.print', function() + -- vim.print() returns its args. + eq({42, 'abc', { a = { b = 77 }}}, + exec_lua[[return {vim.print(42, 'abc', { a = { b = 77 }})}]]) + + -- vim.print() pretty-prints the args. + eq(dedent[[ + + 42 + abc + { + a = { + b = 77 + } + }]], + eval[[execute('lua vim.print(42, "abc", { a = { b = 77 }})')]]) + end) + + it('vim.F.if_nil', function() + local function if_nil(...) + return exec_lua([[ + local args = {...} + local nargs = select('#', ...) + for i = 1, nargs do + if args[i] == vim.NIL then + args[i] = nil + end + end + return vim.F.if_nil(unpack(args, 1, nargs)) + ]], ...) + end + + local a = NIL + local b = NIL + local c = 42 + local d = false + eq(42, if_nil(a, c)) + eq(false, if_nil(d, b)) + eq(42, if_nil(a, b, c, d)) + eq(false, if_nil(d)) + eq(false, if_nil(d, c)) + eq(NIL, if_nil(a)) + end) + + it('lpeg', function() + eq(5, exec_lua [[ + local m = vim.lpeg + return m.match(m.R'09'^1, '4504ab') + ]]) + + eq(4, exec_lua [[ return vim.re.match("abcde", '[a-c]+') ]]) + end) + + it("vim.ringbuf", function() + local results = exec_lua([[ + local ringbuf = vim.ringbuf(3) + ringbuf:push("a") -- idx: 0 + local peeka1 = ringbuf:peek() + local peeka2 = ringbuf:peek() + local popa = ringbuf:pop() + local popnil = ringbuf:pop() + ringbuf:push("a") -- idx: 1 + ringbuf:push("b") -- idx: 2 + + -- doesn't read last added item, but uses separate read index + local pop_after_add_b = ringbuf:pop() + + ringbuf:push("c") -- idx: 3 wraps around, overrides idx: 0 "a" + ringbuf:push("d") -- idx: 4 wraps around, overrides idx: 1 "a" + return { + peeka1 = peeka1, + peeka2 = peeka2, + pop1 = popa, + pop2 = popnil, + pop3 = ringbuf:pop(), + pop4 = ringbuf:pop(), + pop5 = ringbuf:pop(), + pop_after_add_b = pop_after_add_b, + } + ]]) + local expected = { + peeka1 = "a", + peeka2 = "a", + pop1 = "a", + pop2 = nil, + pop3 = "b", + pop4 = "c", + pop5 = "d", + pop_after_add_b = "a", + } + eq(expected, results) + end) end) describe('lua: builtin modules', function() |