commit a5e582dab6debf9048ac81b29c8cf1ab41983369
parent 0a6a73fd254e7b703e8ed521acccfa53e348afd8
Author: Lewis Russell <lewis6991@gmail.com>
Date: Wed, 20 Nov 2024 15:59:15 +0000
test: move lua option/variable tests to a separate file
Diffstat:
2 files changed, 1194 insertions(+), 1166 deletions(-)
diff --git a/test/functional/lua/option_and_var_spec.lua b/test/functional/lua/option_and_var_spec.lua
@@ -0,0 +1,1194 @@
+local t = require('test.testutil')
+local n = require('test.functional.testnvim')()
+local Screen = require('test.functional.ui.screen')
+
+local NIL = vim.NIL
+local feed = n.feed
+local command = n.command
+local clear = n.clear
+local api = n.api
+local eq = t.eq
+local eval = n.eval
+local exec = n.exec
+local exec_lua = n.exec_lua
+local fn = n.fn
+local matches = t.matches
+local mkdir_p = n.mkdir_p
+local pcall_err = t.pcall_err
+local rmdir = n.rmdir
+local write_file = t.write_file
+
+local function eq_exec_lua(expected, f)
+ eq(expected, exec_lua(f))
+end
+
+describe('lua stdlib', function()
+ before_each(clear)
+
+ describe('variables', function()
+ it('vim.g', function()
+ exec_lua(function()
+ vim.api.nvim_set_var('testing', 'hi')
+ vim.api.nvim_set_var('other', 123)
+ vim.api.nvim_set_var('floaty', 5120.1)
+ vim.api.nvim_set_var('nullvar', vim.NIL)
+ vim.api.nvim_set_var('to_delete', { hello = 'world' })
+ end)
+
+ eq('hi', fn.luaeval 'vim.g.testing')
+ eq(123, fn.luaeval 'vim.g.other')
+ eq(5120.1, fn.luaeval 'vim.g.floaty')
+ eq(NIL, fn.luaeval 'vim.g.nonexistent')
+ eq(NIL, fn.luaeval 'vim.g.nullvar')
+ -- lost over RPC, so test locally:
+ eq_exec_lua({ false, true }, function()
+ return { vim.g.nonexistent == vim.NIL, vim.g.nullvar == vim.NIL }
+ end)
+
+ eq({ hello = 'world' }, fn.luaeval 'vim.g.to_delete')
+ exec_lua [[
+ vim.g.to_delete = nil
+ ]]
+ eq(NIL, fn.luaeval 'vim.g.to_delete')
+
+ matches([[attempt to index .* nil value]], pcall_err(exec_lua, 'return vim.g[0].testing'))
+
+ exec_lua(function()
+ local counter = 0
+ local function add_counter()
+ counter = counter + 1
+ end
+ local function get_counter()
+ return counter
+ end
+ vim.g.AddCounter = add_counter
+ vim.g.GetCounter = get_counter
+ vim.g.fn = { add = add_counter, get = get_counter }
+ vim.g.AddParens = function(s)
+ return '(' .. s .. ')'
+ end
+ end)
+
+ eq(0, eval('g:GetCounter()'))
+ eval('g:AddCounter()')
+ eq(1, eval('g:GetCounter()'))
+ eval('g:AddCounter()')
+ eq(2, eval('g:GetCounter()'))
+ exec_lua([[vim.g.AddCounter()]])
+ eq(3, exec_lua([[return vim.g.GetCounter()]]))
+ exec_lua([[vim.api.nvim_get_var('AddCounter')()]])
+ eq(4, exec_lua([[return vim.api.nvim_get_var('GetCounter')()]]))
+ exec_lua([[vim.g.fn.add()]])
+ eq(5, exec_lua([[return vim.g.fn.get()]]))
+ exec_lua([[vim.api.nvim_get_var('fn').add()]])
+ eq(6, exec_lua([[return vim.api.nvim_get_var('fn').get()]]))
+ eq('((foo))', eval([['foo'->AddParens()->AddParens()]]))
+
+ exec_lua(function()
+ local counter = 0
+ local function add_counter()
+ counter = counter + 1
+ end
+ local function get_counter()
+ return counter
+ end
+ vim.api.nvim_set_var('AddCounter', add_counter)
+ vim.api.nvim_set_var('GetCounter', get_counter)
+ vim.api.nvim_set_var('fn', { add = add_counter, get = get_counter })
+ vim.api.nvim_set_var('AddParens', function(s)
+ return '(' .. s .. ')'
+ end)
+ end)
+
+ eq(0, eval('g:GetCounter()'))
+ eval('g:AddCounter()')
+ eq(1, eval('g:GetCounter()'))
+ eval('g:AddCounter()')
+ eq(2, eval('g:GetCounter()'))
+ exec_lua([[vim.g.AddCounter()]])
+ eq(3, exec_lua([[return vim.g.GetCounter()]]))
+ exec_lua([[vim.api.nvim_get_var('AddCounter')()]])
+ eq(4, exec_lua([[return vim.api.nvim_get_var('GetCounter')()]]))
+ exec_lua([[vim.g.fn.add()]])
+ eq(5, exec_lua([[return vim.g.fn.get()]]))
+ exec_lua([[vim.api.nvim_get_var('fn').add()]])
+ eq(6, exec_lua([[return vim.api.nvim_get_var('fn').get()]]))
+ eq('((foo))', eval([['foo'->AddParens()->AddParens()]]))
+
+ exec([[
+ function Test()
+ endfunction
+ function s:Test()
+ endfunction
+ let g:Unknown_func = function('Test')
+ let g:Unknown_script_func = function('s:Test')
+ ]])
+ eq(NIL, exec_lua([[return vim.g.Unknown_func]]))
+ eq(NIL, exec_lua([[return vim.g.Unknown_script_func]]))
+
+ -- Check if autoload works properly
+ local pathsep = n.get_pathsep()
+ local xconfig = 'Xhome' .. pathsep .. 'Xconfig'
+ local xdata = 'Xhome' .. pathsep .. 'Xdata'
+ local autoload_folder = table.concat({ xconfig, 'nvim', 'autoload' }, pathsep)
+ local autoload_file = table.concat({ autoload_folder, 'testload.vim' }, pathsep)
+ mkdir_p(autoload_folder)
+ write_file(autoload_file, [[let testload#value = 2]])
+
+ clear { args_rm = { '-u' }, env = { XDG_CONFIG_HOME = xconfig, XDG_DATA_HOME = xdata } }
+
+ eq(2, exec_lua("return vim.g['testload#value']"))
+ rmdir('Xhome')
+ end)
+
+ it('vim.b', function()
+ exec_lua(function()
+ vim.api.nvim_buf_set_var(0, 'testing', 'hi')
+ vim.api.nvim_buf_set_var(0, 'other', 123)
+ vim.api.nvim_buf_set_var(0, 'floaty', 5120.1)
+ vim.api.nvim_buf_set_var(0, 'nullvar', vim.NIL)
+ vim.api.nvim_buf_set_var(0, 'to_delete', { hello = 'world' })
+ _G.BUF = vim.api.nvim_create_buf(false, true)
+ vim.api.nvim_buf_set_var(BUF, 'testing', 'bye')
+ end)
+
+ eq('hi', fn.luaeval 'vim.b.testing')
+ eq('bye', fn.luaeval 'vim.b[BUF].testing')
+ eq(123, fn.luaeval 'vim.b.other')
+ eq(5120.1, fn.luaeval 'vim.b.floaty')
+ eq(NIL, fn.luaeval 'vim.b.nonexistent')
+ eq(NIL, fn.luaeval 'vim.b[BUF].nonexistent')
+ eq(NIL, fn.luaeval 'vim.b.nullvar')
+ -- lost over RPC, so test locally:
+ eq_exec_lua({ false, true }, function()
+ return { vim.b.nonexistent == vim.NIL, vim.b.nullvar == vim.NIL }
+ end)
+
+ matches([[attempt to index .* nil value]], pcall_err(exec_lua, 'return vim.b[BUF][0].testing'))
+
+ eq({ hello = 'world' }, fn.luaeval 'vim.b.to_delete')
+ exec_lua [[
+ vim.b.to_delete = nil
+ ]]
+ eq(NIL, fn.luaeval 'vim.b.to_delete')
+
+ exec_lua(function()
+ local counter = 0
+ local function add_counter() counter = counter + 1 end
+ local function get_counter() return counter end
+ vim.b.AddCounter = add_counter
+ vim.b.GetCounter = get_counter
+ vim.b.fn = {add = add_counter, get = get_counter}
+ vim.b.AddParens = function(s) return '(' .. s .. ')' end
+ end)
+
+ eq(0, eval('b:GetCounter()'))
+ eval('b:AddCounter()')
+ eq(1, eval('b:GetCounter()'))
+ eval('b:AddCounter()')
+ eq(2, eval('b:GetCounter()'))
+ exec_lua([[vim.b.AddCounter()]])
+ eq(3, exec_lua([[return vim.b.GetCounter()]]))
+ exec_lua([[vim.api.nvim_buf_get_var(0, 'AddCounter')()]])
+ eq(4, exec_lua([[return vim.api.nvim_buf_get_var(0, 'GetCounter')()]]))
+ exec_lua([[vim.b.fn.add()]])
+ eq(5, exec_lua([[return vim.b.fn.get()]]))
+ exec_lua([[vim.api.nvim_buf_get_var(0, 'fn').add()]])
+ eq(6, exec_lua([[return vim.api.nvim_buf_get_var(0, 'fn').get()]]))
+ eq('((foo))', eval([['foo'->b:AddParens()->b:AddParens()]]))
+
+ exec_lua(function()
+ local counter = 0
+ local function add_counter() counter = counter + 1 end
+ local function get_counter() return counter end
+ vim.api.nvim_buf_set_var(0, 'AddCounter', add_counter)
+ vim.api.nvim_buf_set_var(0, 'GetCounter', get_counter)
+ vim.api.nvim_buf_set_var(0, 'fn', {add = add_counter, get = get_counter})
+ vim.api.nvim_buf_set_var(0, 'AddParens', function(s) return '(' .. s .. ')' end)
+ end)
+
+ eq(0, eval('b:GetCounter()'))
+ eval('b:AddCounter()')
+ eq(1, eval('b:GetCounter()'))
+ eval('b:AddCounter()')
+ eq(2, eval('b:GetCounter()'))
+ exec_lua([[vim.b.AddCounter()]])
+ eq(3, exec_lua([[return vim.b.GetCounter()]]))
+ exec_lua([[vim.api.nvim_buf_get_var(0, 'AddCounter')()]])
+ eq(4, exec_lua([[return vim.api.nvim_buf_get_var(0, 'GetCounter')()]]))
+ exec_lua([[vim.b.fn.add()]])
+ eq(5, exec_lua([[return vim.b.fn.get()]]))
+ exec_lua([[vim.api.nvim_buf_get_var(0, 'fn').add()]])
+ eq(6, exec_lua([[return vim.api.nvim_buf_get_var(0, 'fn').get()]]))
+ eq('((foo))', eval([['foo'->b:AddParens()->b:AddParens()]]))
+
+ exec([[
+ function Test()
+ endfunction
+ function s:Test()
+ endfunction
+ let b:Unknown_func = function('Test')
+ let b:Unknown_script_func = function('s:Test')
+ ]])
+ eq(NIL, exec_lua([[return vim.b.Unknown_func]]))
+ eq(NIL, exec_lua([[return vim.b.Unknown_script_func]]))
+
+ exec_lua [[
+ vim.cmd "vnew"
+ ]]
+
+ eq(NIL, fn.luaeval 'vim.b.testing')
+ eq(NIL, fn.luaeval 'vim.b.other')
+ eq(NIL, fn.luaeval 'vim.b.nonexistent')
+ end)
+
+ it('vim.w', function()
+ exec_lua [[
+ vim.api.nvim_win_set_var(0, "testing", "hi")
+ vim.api.nvim_win_set_var(0, "other", 123)
+ vim.api.nvim_win_set_var(0, "to_delete", {hello="world"})
+ BUF = vim.api.nvim_create_buf(false, true)
+ WIN = vim.api.nvim_open_win(BUF, false, {
+ width=10, height=10,
+ relative='win', row=0, col=0
+ })
+ vim.api.nvim_win_set_var(WIN, "testing", "bye")
+ ]]
+
+ eq('hi', fn.luaeval 'vim.w.testing')
+ eq('bye', fn.luaeval 'vim.w[WIN].testing')
+ eq(123, fn.luaeval 'vim.w.other')
+ eq(NIL, fn.luaeval 'vim.w.nonexistent')
+ eq(NIL, fn.luaeval 'vim.w[WIN].nonexistent')
+
+ matches([[attempt to index .* nil value]], pcall_err(exec_lua, 'return vim.w[WIN][0].testing'))
+
+ eq({ hello = 'world' }, fn.luaeval 'vim.w.to_delete')
+ exec_lua [[
+ vim.w.to_delete = nil
+ ]]
+ eq(NIL, fn.luaeval 'vim.w.to_delete')
+
+ exec_lua [[
+ local counter = 0
+ local function add_counter() counter = counter + 1 end
+ local function get_counter() return counter end
+ vim.w.AddCounter = add_counter
+ vim.w.GetCounter = get_counter
+ vim.w.fn = {add = add_counter, get = get_counter}
+ vim.w.AddParens = function(s) return '(' .. s .. ')' end
+ ]]
+
+ eq(0, eval('w:GetCounter()'))
+ eval('w:AddCounter()')
+ eq(1, eval('w:GetCounter()'))
+ eval('w:AddCounter()')
+ eq(2, eval('w:GetCounter()'))
+ exec_lua([[vim.w.AddCounter()]])
+ eq(3, exec_lua([[return vim.w.GetCounter()]]))
+ exec_lua([[vim.api.nvim_win_get_var(0, 'AddCounter')()]])
+ eq(4, exec_lua([[return vim.api.nvim_win_get_var(0, 'GetCounter')()]]))
+ exec_lua([[vim.w.fn.add()]])
+ eq(5, exec_lua([[return vim.w.fn.get()]]))
+ exec_lua([[vim.api.nvim_win_get_var(0, 'fn').add()]])
+ eq(6, exec_lua([[return vim.api.nvim_win_get_var(0, 'fn').get()]]))
+ eq('((foo))', eval([['foo'->w:AddParens()->w:AddParens()]]))
+
+ exec_lua [[
+ local counter = 0
+ local function add_counter() counter = counter + 1 end
+ local function get_counter() return counter end
+ vim.api.nvim_win_set_var(0, 'AddCounter', add_counter)
+ vim.api.nvim_win_set_var(0, 'GetCounter', get_counter)
+ vim.api.nvim_win_set_var(0, 'fn', {add = add_counter, get = get_counter})
+ vim.api.nvim_win_set_var(0, 'AddParens', function(s) return '(' .. s .. ')' end)
+ ]]
+
+ eq(0, eval('w:GetCounter()'))
+ eval('w:AddCounter()')
+ eq(1, eval('w:GetCounter()'))
+ eval('w:AddCounter()')
+ eq(2, eval('w:GetCounter()'))
+ exec_lua([[vim.w.AddCounter()]])
+ eq(3, exec_lua([[return vim.w.GetCounter()]]))
+ exec_lua([[vim.api.nvim_win_get_var(0, 'AddCounter')()]])
+ eq(4, exec_lua([[return vim.api.nvim_win_get_var(0, 'GetCounter')()]]))
+ exec_lua([[vim.w.fn.add()]])
+ eq(5, exec_lua([[return vim.w.fn.get()]]))
+ exec_lua([[vim.api.nvim_win_get_var(0, 'fn').add()]])
+ eq(6, exec_lua([[return vim.api.nvim_win_get_var(0, 'fn').get()]]))
+ eq('((foo))', eval([['foo'->w:AddParens()->w:AddParens()]]))
+
+ exec([[
+ function Test()
+ endfunction
+ function s:Test()
+ endfunction
+ let w:Unknown_func = function('Test')
+ let w:Unknown_script_func = function('s:Test')
+ ]])
+ eq(NIL, exec_lua([[return vim.w.Unknown_func]]))
+ eq(NIL, exec_lua([[return vim.w.Unknown_script_func]]))
+
+ exec_lua [[
+ vim.cmd "vnew"
+ ]]
+
+ eq(NIL, fn.luaeval 'vim.w.testing')
+ eq(NIL, fn.luaeval 'vim.w.other')
+ eq(NIL, fn.luaeval 'vim.w.nonexistent')
+ end)
+
+ it('vim.t', function()
+ exec_lua [[
+ vim.api.nvim_tabpage_set_var(0, "testing", "hi")
+ vim.api.nvim_tabpage_set_var(0, "other", 123)
+ vim.api.nvim_tabpage_set_var(0, "to_delete", {hello="world"})
+ ]]
+
+ eq('hi', fn.luaeval 'vim.t.testing')
+ eq(123, fn.luaeval 'vim.t.other')
+ eq(NIL, fn.luaeval 'vim.t.nonexistent')
+ eq('hi', fn.luaeval 'vim.t[0].testing')
+ eq(123, fn.luaeval 'vim.t[0].other')
+ eq(NIL, fn.luaeval 'vim.t[0].nonexistent')
+
+ matches([[attempt to index .* nil value]], pcall_err(exec_lua, 'return vim.t[0][0].testing'))
+
+ eq({ hello = 'world' }, fn.luaeval 'vim.t.to_delete')
+ exec_lua [[
+ vim.t.to_delete = nil
+ ]]
+ eq(NIL, fn.luaeval 'vim.t.to_delete')
+
+ exec_lua [[
+ local counter = 0
+ local function add_counter() counter = counter + 1 end
+ local function get_counter() return counter end
+ vim.t.AddCounter = add_counter
+ vim.t.GetCounter = get_counter
+ vim.t.fn = {add = add_counter, get = get_counter}
+ vim.t.AddParens = function(s) return '(' .. s .. ')' end
+ ]]
+
+ eq(0, eval('t:GetCounter()'))
+ eval('t:AddCounter()')
+ eq(1, eval('t:GetCounter()'))
+ eval('t:AddCounter()')
+ eq(2, eval('t:GetCounter()'))
+ exec_lua([[vim.t.AddCounter()]])
+ eq(3, exec_lua([[return vim.t.GetCounter()]]))
+ exec_lua([[vim.api.nvim_tabpage_get_var(0, 'AddCounter')()]])
+ eq(4, exec_lua([[return vim.api.nvim_tabpage_get_var(0, 'GetCounter')()]]))
+ exec_lua([[vim.t.fn.add()]])
+ eq(5, exec_lua([[return vim.t.fn.get()]]))
+ exec_lua([[vim.api.nvim_tabpage_get_var(0, 'fn').add()]])
+ eq(6, exec_lua([[return vim.api.nvim_tabpage_get_var(0, 'fn').get()]]))
+ eq('((foo))', eval([['foo'->t:AddParens()->t:AddParens()]]))
+
+ exec_lua [[
+ local counter = 0
+ local function add_counter() counter = counter + 1 end
+ local function get_counter() return counter end
+ vim.api.nvim_tabpage_set_var(0, 'AddCounter', add_counter)
+ vim.api.nvim_tabpage_set_var(0, 'GetCounter', get_counter)
+ vim.api.nvim_tabpage_set_var(0, 'fn', {add = add_counter, get = get_counter})
+ vim.api.nvim_tabpage_set_var(0, 'AddParens', function(s) return '(' .. s .. ')' end)
+ ]]
+
+ eq(0, eval('t:GetCounter()'))
+ eval('t:AddCounter()')
+ eq(1, eval('t:GetCounter()'))
+ eval('t:AddCounter()')
+ eq(2, eval('t:GetCounter()'))
+ exec_lua([[vim.t.AddCounter()]])
+ eq(3, exec_lua([[return vim.t.GetCounter()]]))
+ exec_lua([[vim.api.nvim_tabpage_get_var(0, 'AddCounter')()]])
+ eq(4, exec_lua([[return vim.api.nvim_tabpage_get_var(0, 'GetCounter')()]]))
+ exec_lua([[vim.t.fn.add()]])
+ eq(5, exec_lua([[return vim.t.fn.get()]]))
+ exec_lua([[vim.api.nvim_tabpage_get_var(0, 'fn').add()]])
+ eq(6, exec_lua([[return vim.api.nvim_tabpage_get_var(0, 'fn').get()]]))
+ eq('((foo))', eval([['foo'->t:AddParens()->t:AddParens()]]))
+
+ exec_lua [[
+ vim.cmd "tabnew"
+ ]]
+
+ eq(NIL, fn.luaeval 'vim.t.testing')
+ eq(NIL, fn.luaeval 'vim.t.other')
+ eq(NIL, fn.luaeval 'vim.t.nonexistent')
+ end)
+
+ it('vim.env', function()
+ exec_lua([[vim.fn.setenv('A', 123)]])
+ eq('123', fn.luaeval('vim.env.A'))
+ exec_lua([[vim.env.A = 456]])
+ eq('456', fn.luaeval('vim.env.A'))
+ exec_lua([[vim.env.A = nil]])
+ eq(NIL, fn.luaeval('vim.env.A'))
+
+ eq(true, fn.luaeval('vim.env.B == nil'))
+
+ command([[let $HOME = 'foo']])
+ eq('foo', fn.expand('~'))
+ eq('foo', fn.luaeval('vim.env.HOME'))
+ exec_lua([[vim.env.HOME = nil]])
+ eq('foo', fn.expand('~'))
+ exec_lua([[vim.env.HOME = 'bar']])
+ eq('bar', fn.expand('~'))
+ eq('bar', fn.luaeval('vim.env.HOME'))
+ end)
+
+ it('vim.v', function()
+ eq(fn.luaeval "vim.api.nvim_get_vvar('progpath')", fn.luaeval 'vim.v.progpath')
+ eq(false, fn.luaeval "vim.v['false']")
+ eq(NIL, fn.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('Dict 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 }, api.nvim_win_get_cursor(0))
+ eq(1, eval('v:searchforward'))
+ feed('n')
+ eq({ 1, 5 }, api.nvim_win_get_cursor(0))
+ exec_lua([[vim.v.searchforward = 0]])
+ eq(0, eval('v:searchforward'))
+ feed('n')
+ eq({ 1, 1 }, api.nvim_win_get_cursor(0))
+ exec_lua([[vim.v.searchforward = 1]])
+ eq(1, eval('v:searchforward'))
+ feed('n')
+ eq({ 1, 5 }, api.nvim_win_get_cursor(0))
+
+ local screen = Screen.new(60, 3)
+ eq(1, eval('v:hlsearch'))
+ screen:expect {
+ grid = [[
+ {10:foo} {10:^foo} {10:foo} |
+ {1:~ }|
+ |
+ ]],
+ }
+ exec_lua([[vim.v.hlsearch = 0]])
+ eq(0, eval('v:hlsearch'))
+ screen:expect {
+ grid = [[
+ foo ^foo foo |
+ {1:~ }|
+ |
+ ]],
+ }
+ exec_lua([[vim.v.hlsearch = 1]])
+ eq(1, eval('v:hlsearch'))
+ screen:expect {
+ grid = [[
+ {10:foo} {10:^foo} {10:foo} |
+ {1:~ }|
+ |
+ ]],
+ }
+ end)
+ end)
+
+ describe('options', function()
+ it('vim.bo', function()
+ eq('', fn.luaeval 'vim.bo.filetype')
+ exec_lua(function()
+ _G.BUF = vim.api.nvim_create_buf(false, true)
+ vim.api.nvim_set_option_value('filetype', 'markdown', {})
+ vim.api.nvim_set_option_value('modifiable', false, { buf = _G.BUF })
+ end)
+ eq(false, fn.luaeval 'vim.bo.modified')
+ eq('markdown', fn.luaeval 'vim.bo.filetype')
+ eq(false, fn.luaeval 'vim.bo[BUF].modifiable')
+ exec_lua(function()
+ vim.bo.filetype = ''
+ vim.bo[_G.BUF].modifiable = true
+ end)
+ eq('', fn.luaeval 'vim.bo.filetype')
+ eq(true, fn.luaeval 'vim.bo[BUF].modifiable')
+ matches("Unknown option 'nosuchopt'$", pcall_err(exec_lua, 'return vim.bo.nosuchopt'))
+ 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'))
+ end)
+
+ it('vim.wo', function()
+ exec_lua(function()
+ vim.api.nvim_set_option_value('cole', 2, {})
+ vim.cmd 'split'
+ vim.api.nvim_set_option_value('cole', 2, {})
+ end)
+ eq(2, fn.luaeval 'vim.wo.cole')
+ exec_lua(function()
+ vim.wo.conceallevel = 0
+ end)
+ eq(0, fn.luaeval 'vim.wo.cole')
+ eq(0, fn.luaeval 'vim.wo[0].cole')
+ eq(0, fn.luaeval 'vim.wo[1001].cole')
+ matches("Unknown option 'notanopt'$", pcall_err(exec_lua, 'return vim.wo.notanopt'))
+ matches('Invalid window id: %-1$', pcall_err(exec_lua, 'return vim.wo[-1].list'))
+ eq(2, fn.luaeval 'vim.wo[1000].cole')
+ exec_lua(function()
+ vim.wo[1000].cole = 0
+ end)
+ eq(0, fn.luaeval 'vim.wo[1000].cole')
+
+ -- Can handle global-local values
+ exec_lua [[vim.o.scrolloff = 100]]
+ exec_lua [[vim.wo.scrolloff = 200]]
+ eq(200, fn.luaeval 'vim.wo.scrolloff')
+ exec_lua [[vim.wo.scrolloff = -1]]
+ eq(100, fn.luaeval 'vim.wo.scrolloff')
+ exec_lua(function()
+ vim.wo[0][0].scrolloff = 200
+ vim.cmd 'enew'
+ end)
+ eq(100, fn.luaeval 'vim.wo.scrolloff')
+
+ matches('only bufnr=0 is supported', pcall_err(exec_lua, 'vim.wo[0][10].signcolumn = "no"'))
+
+ matches('only bufnr=0 is supported', pcall_err(exec_lua, 'local a = vim.wo[0][10].signcolumn'))
+ end)
+
+ describe('vim.opt', function()
+ -- TODO: We still need to write some tests for optlocal, opt and then getting the options
+ -- Probably could also do some stuff with getting things from viml side as well to confirm behavior is the same.
+
+ it('allows setting number values', function()
+ local scrolloff = exec_lua [[
+ vim.opt.scrolloff = 10
+ return vim.o.scrolloff
+ ]]
+ eq(10, scrolloff)
+ end)
+
+ pending('handles STUPID window things', function()
+ eq_exec_lua({}, function()
+ return {
+ vim.api.nvim_get_option_value('scrolloff', { scope = 'global' }),
+ vim.api.nvim_get_option_value('scrolloff', { win = 0 }),
+ }
+ end)
+ end)
+
+ it('allows setting tables', function()
+ eq_exec_lua('hello,world', function()
+ vim.opt.wildignore = { 'hello', 'world' }
+ return vim.o.wildignore
+ end)
+ end)
+
+ it('allows setting tables with shortnames', function()
+ eq_exec_lua('hello,world', function()
+ vim.opt.wig = { 'hello', 'world' }
+ return vim.o.wildignore
+ end)
+ end)
+
+ it('errors when you attempt to set string values to numeric options', function()
+ eq_exec_lua(false, function()
+ return ({
+ pcall(function()
+ vim.opt.textwidth = 'hello world'
+ end),
+ })[1]
+ end)
+ end)
+
+ it('errors when you attempt to setlocal a global value', function()
+ eq_exec_lua(false, function()
+ return pcall(function()
+ vim.opt_local.clipboard = 'hello'
+ end)
+ end)
+ end)
+
+ it('allows you to set boolean values', function()
+ eq_exec_lua({ true, false, true }, function()
+ local results = {}
+
+ vim.opt.autoindent = true
+ table.insert(results, vim.bo.autoindent)
+
+ vim.opt.autoindent = false
+ table.insert(results, vim.bo.autoindent)
+
+ vim.opt.autoindent = not vim.opt.autoindent:get()
+ table.insert(results, vim.bo.autoindent)
+
+ return results
+ end)
+ end)
+
+ it('changes current buffer values and defaults for global local values', function()
+ local result = exec_lua(function()
+ local result = {}
+
+ vim.opt.makeprg = 'global-local'
+ 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.go.makeprg)
+ table.insert(result, vim.api.nvim_get_option_value('makeprg', { buf = 0 }))
+
+ vim.opt_global.makeprg = 'only-global'
+ 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.go.makeprg)
+ table.insert(result, vim.api.nvim_get_option_value('makeprg', { buf = 0 }))
+ return result
+ end)
+
+ -- Set -> global & local
+ eq('global-local', result[1])
+ eq('', result[2])
+
+ -- Setlocal -> only local
+ eq('global-local', result[3])
+ eq('only-local', result[4])
+
+ -- Setglobal -> only global
+ eq('only-global', result[5])
+ eq('only-local', result[6])
+
+ -- Set -> sets global value and resets local value
+ eq('global-local', result[7])
+ eq('', result[8])
+ end)
+
+ it('allows you to retrieve window opts even if they have not been set', function()
+ eq_exec_lua({ false, false, true, true }, function()
+ local result = {}
+ table.insert(result, vim.opt.number:get())
+ table.insert(result, vim.opt_local.number:get())
+
+ vim.opt_local.number = true
+ table.insert(result, vim.opt.number:get())
+ table.insert(result, vim.opt_local.number:get())
+
+ return result
+ end)
+ end)
+
+ it('allows all sorts of string manipulation', function()
+ eq_exec_lua({ 'hello', 'hello world', 'start hello world' }, function()
+ local results = {}
+
+ vim.opt.makeprg = 'hello'
+ table.insert(results, vim.o.makeprg)
+
+ vim.opt.makeprg = vim.opt.makeprg + ' world'
+ table.insert(results, vim.o.makeprg)
+
+ vim.opt.makeprg = vim.opt.makeprg ^ 'start '
+ table.insert(results, vim.o.makeprg)
+
+ return results
+ end)
+ end)
+
+ describe('option:get()', function()
+ it('works for boolean values', function()
+ eq_exec_lua(false, function()
+ vim.opt.number = false
+ return vim.opt.number:get()
+ end)
+ end)
+
+ it('works for number values', function()
+ eq_exec_lua(10, function()
+ vim.opt.tabstop = 10
+ return vim.opt.tabstop:get()
+ end)
+ end)
+
+ it('works for string values', function()
+ eq_exec_lua('hello world', function()
+ vim.opt.makeprg = 'hello world'
+ return vim.opt.makeprg:get()
+ end)
+ end)
+
+ it('works for set type flaglists', function()
+ local formatoptions = exec_lua(function()
+ vim.opt.formatoptions = 'tcro'
+ return vim.opt.formatoptions:get()
+ end)
+
+ eq(true, formatoptions.t)
+ eq(true, not formatoptions.q)
+ end)
+
+ it('works for set type flaglists', function()
+ local formatoptions = exec_lua(function()
+ vim.opt.formatoptions = { t = true, c = true, r = true, o = true }
+ return vim.opt.formatoptions:get()
+ end)
+
+ eq(true, formatoptions.t)
+ eq(true, not formatoptions.q)
+ end)
+
+ it('works for array list type options', function()
+ local wildignore = exec_lua(function()
+ vim.opt.wildignore = '*.c,*.o,__pycache__'
+ return vim.opt.wildignore:get()
+ end)
+
+ eq(3, #wildignore)
+ eq('*.c', wildignore[1])
+ end)
+
+ it('works for options that are both commalist and flaglist', function()
+ eq_exec_lua({ b = true, s = true }, function()
+ vim.opt.whichwrap = 'b,s'
+ return vim.opt.whichwrap:get()
+ end)
+
+ eq_exec_lua({ b = true, h = true }, function()
+ vim.opt.whichwrap = { b = true, s = false, h = true }
+ return vim.opt.whichwrap:get()
+ end)
+ end)
+
+ it('works for key-value pair options', function()
+ eq_exec_lua({ tab = '> ', space = '_' }, function()
+ vim.opt.listchars = 'tab:> ,space:_'
+ return vim.opt.listchars:get()
+ end)
+ end)
+
+ it('allows you to add numeric options', function()
+ eq_exec_lua(16, function()
+ vim.opt.tabstop = 12
+ vim.opt.tabstop = vim.opt.tabstop + 4
+ return vim.bo.tabstop
+ end)
+ end)
+
+ it('allows you to subtract numeric options', function()
+ eq_exec_lua(2, function()
+ vim.opt.tabstop = 4
+ vim.opt.tabstop = vim.opt.tabstop - 2
+ return vim.bo.tabstop
+ end)
+ end)
+ end)
+
+ describe('key:value style options', function()
+ it('handles dict style', function()
+ eq_exec_lua('eol:~,space:.', function()
+ vim.opt.listchars = { eol = '~', space = '.' }
+ return vim.o.listchars
+ end)
+ end)
+
+ it('allows adding dict style', function()
+ eq_exec_lua('eol:~,space:-', function()
+ vim.opt.listchars = { eol = '~', space = '.' }
+ vim.opt.listchars = vim.opt.listchars + { space = '-' }
+ return vim.o.listchars
+ end)
+ end)
+
+ it('allows adding dict style', function()
+ eq_exec_lua('eol:~,space:_', function()
+ vim.opt.listchars = { eol = '~', space = '.' }
+ vim.opt.listchars = vim.opt.listchars + { space = '-' } + { space = '_' }
+ return vim.o.listchars
+ end)
+ end)
+
+ it('allows completely new keys', function()
+ eq_exec_lua('eol:~,space:.,tab:>>>', function()
+ vim.opt.listchars = { eol = '~', space = '.' }
+ vim.opt.listchars = vim.opt.listchars + { tab = '>>>' }
+ return vim.o.listchars
+ end)
+ end)
+
+ it('allows subtracting dict style', function()
+ eq_exec_lua('eol:~', function()
+ vim.opt.listchars = { eol = '~', space = '.' }
+ vim.opt.listchars = vim.opt.listchars - 'space'
+ return vim.o.listchars
+ end)
+ end)
+
+ it('allows subtracting dict style', function()
+ eq_exec_lua('', function()
+ vim.opt.listchars = { eol = '~', space = '.' }
+ vim.opt.listchars = vim.opt.listchars - 'space' - 'eol'
+ return vim.o.listchars
+ end)
+ end)
+
+ it('allows subtracting dict style multiple times', function()
+ eq_exec_lua('eol:~', function()
+ vim.opt.listchars = { eol = '~', space = '.' }
+ vim.opt.listchars = vim.opt.listchars - 'space' - 'space'
+ return vim.o.listchars
+ end)
+ end)
+
+ it('allows adding a key:value string to a listchars', function()
+ eq_exec_lua('eol:~,space:.,tab:>~', function()
+ vim.opt.listchars = { eol = '~', space = '.' }
+ vim.opt.listchars = vim.opt.listchars + 'tab:>~'
+ return vim.o.listchars
+ end)
+ end)
+
+ it('allows prepending a key:value string to a listchars', function()
+ eq_exec_lua('eol:~,space:.,tab:>~', function()
+ vim.opt.listchars = { eol = '~', space = '.' }
+ vim.opt.listchars = vim.opt.listchars ^ 'tab:>~'
+ return vim.o.listchars
+ end)
+ end)
+ end)
+
+ it('automatically sets when calling remove', function()
+ eq_exec_lua('foo,baz', function()
+ vim.opt.wildignore = 'foo,bar,baz'
+ vim.opt.wildignore:remove('bar')
+ return vim.o.wildignore
+ end)
+ end)
+
+ it('automatically sets when calling remove with a table', function()
+ eq_exec_lua('foo', function()
+ vim.opt.wildignore = 'foo,bar,baz'
+ vim.opt.wildignore:remove { 'bar', 'baz' }
+ return vim.o.wildignore
+ end)
+ end)
+
+ it('automatically sets when calling append', function()
+ eq_exec_lua('foo,bar,baz,bing', function()
+ vim.opt.wildignore = 'foo,bar,baz'
+ vim.opt.wildignore:append('bing')
+ return vim.o.wildignore
+ end)
+ end)
+
+ it('automatically sets when calling append with a table', function()
+ eq_exec_lua('foo,bar,baz,bing,zap', function()
+ vim.opt.wildignore = 'foo,bar,baz'
+ vim.opt.wildignore:append { 'bing', 'zap' }
+ return vim.o.wildignore
+ end)
+ end)
+
+ it('allows adding tables', function()
+ eq_exec_lua('foo', function()
+ vim.opt.wildignore = 'foo'
+ return vim.o.wildignore
+ end)
+
+ eq_exec_lua('foo,bar,baz', function()
+ vim.opt.wildignore = vim.opt.wildignore + { 'bar', 'baz' }
+ return vim.o.wildignore
+ end)
+ end)
+
+ it('handles adding duplicates', function()
+ eq_exec_lua('foo', function()
+ vim.opt.wildignore = 'foo'
+ return vim.o.wildignore
+ end)
+
+ eq_exec_lua('foo,bar,baz', function()
+ vim.opt.wildignore = vim.opt.wildignore + { 'bar', 'baz' }
+ return vim.o.wildignore
+ end)
+
+ eq_exec_lua('foo,bar,baz', function()
+ vim.opt.wildignore = vim.opt.wildignore + { 'bar', 'baz' }
+ return vim.o.wildignore
+ end)
+ end)
+
+ it('allows adding multiple times', function()
+ eq_exec_lua('foo,bar,baz', function()
+ vim.opt.wildignore = 'foo'
+ vim.opt.wildignore = vim.opt.wildignore + 'bar' + 'baz'
+ return vim.o.wildignore
+ end)
+ end)
+
+ it('removes values when you use minus', function()
+ eq_exec_lua('foo', function()
+ vim.opt.wildignore = 'foo'
+ return vim.o.wildignore
+ end)
+
+ eq_exec_lua('foo,bar,baz', function()
+ vim.opt.wildignore = vim.opt.wildignore + { 'bar', 'baz' }
+ return vim.o.wildignore
+ end)
+
+ eq_exec_lua('foo,baz', function()
+ vim.opt.wildignore = vim.opt.wildignore - 'bar'
+ return vim.o.wildignore
+ end)
+ end)
+
+ it('prepends values when using ^', function()
+ eq_exec_lua('first,foo', function()
+ vim.opt.wildignore = 'foo'
+ vim.opt.wildignore = vim.opt.wildignore ^ 'first'
+ return vim.o.wildignore
+ end)
+
+ eq_exec_lua('super_first,first,foo', function()
+ vim.opt.wildignore = vim.opt.wildignore ^ 'super_first'
+ return vim.o.wildignore
+ end)
+ end)
+
+ it('does not remove duplicates from wildmode: #14708', function()
+ eq_exec_lua('full,list,full', function()
+ vim.opt.wildmode = { 'full', 'list', 'full' }
+ return vim.o.wildmode
+ end)
+ end)
+
+ describe('option types', function()
+ it('allows to set option with numeric value', function()
+ eq_exec_lua(4, function()
+ vim.opt.tabstop = 4
+ return vim.bo.tabstop
+ end)
+
+ matches(
+ "Invalid option type 'string' for 'tabstop'",
+ pcall_err(exec_lua, [[vim.opt.tabstop = '4']])
+ )
+ matches(
+ "Invalid option type 'boolean' for 'tabstop'",
+ pcall_err(exec_lua, [[vim.opt.tabstop = true]])
+ )
+ matches(
+ "Invalid option type 'table' for 'tabstop'",
+ pcall_err(exec_lua, [[vim.opt.tabstop = {4, 2}]])
+ )
+ matches(
+ "Invalid option type 'function' for 'tabstop'",
+ pcall_err(exec_lua, [[vim.opt.tabstop = function() return 4 end]])
+ )
+ end)
+
+ it('allows to set option with boolean value', function()
+ eq_exec_lua(true, function()
+ vim.opt.undofile = true
+ return vim.bo.undofile
+ end)
+
+ matches(
+ "Invalid option type 'number' for 'undofile'",
+ pcall_err(exec_lua, [[vim.opt.undofile = 0]])
+ )
+ matches(
+ "Invalid option type 'table' for 'undofile'",
+ pcall_err(exec_lua, [[vim.opt.undofile = {true}]])
+ )
+ matches(
+ "Invalid option type 'string' for 'undofile'",
+ pcall_err(exec_lua, [[vim.opt.undofile = 'true']])
+ )
+ matches(
+ "Invalid option type 'function' for 'undofile'",
+ pcall_err(exec_lua, [[vim.opt.undofile = function() return true end]])
+ )
+ end)
+
+ it('allows to set option with array or string value', function()
+ eq_exec_lua('indent,eol,start', function()
+ vim.opt.backspace = { 'indent', 'eol', 'start' }
+ return vim.go.backspace
+ end)
+
+ eq_exec_lua('indent,eol,start', function()
+ vim.opt.backspace = 'indent,eol,start'
+ return vim.go.backspace
+ end)
+
+ matches(
+ "Invalid option type 'boolean' for 'backspace'",
+ pcall_err(exec_lua, [[vim.opt.backspace = true]])
+ )
+ matches(
+ "Invalid option type 'number' for 'backspace'",
+ pcall_err(exec_lua, [[vim.opt.backspace = 2]])
+ )
+ matches(
+ "Invalid option type 'function' for 'backspace'",
+ pcall_err(exec_lua, [[vim.opt.backspace = function() return 'indent,eol,start' end]])
+ )
+ end)
+
+ it('allows set option with map or string value', function()
+ eq_exec_lua('eol:~,space:.', function()
+ vim.opt.listchars = { eol = '~', space = '.' }
+ return vim.o.listchars
+ end)
+
+ eq_exec_lua('eol:~,space:.,tab:>~', function()
+ vim.opt.listchars = 'eol:~,space:.,tab:>~'
+ return vim.o.listchars
+ end)
+
+ matches(
+ "Invalid option type 'boolean' for 'listchars'",
+ pcall_err(exec_lua, [[vim.opt.listchars = true]])
+ )
+ matches(
+ "Invalid option type 'number' for 'listchars'",
+ pcall_err(exec_lua, [[vim.opt.listchars = 2]])
+ )
+ matches(
+ "Invalid option type 'function' for 'listchars'",
+ pcall_err(exec_lua, [[vim.opt.listchars = function() return "eol:~,space:.,tab:>~" end]])
+ )
+ end)
+
+ it('allows set option with set or string value', function()
+ eq_exec_lua('b,s', function()
+ vim.opt.whichwrap = { b = true, s = 1 }
+ return vim.go.whichwrap
+ end)
+
+ eq_exec_lua('b,s,<,>,[,]', function()
+ vim.opt.whichwrap = 'b,s,<,>,[,]'
+ return vim.go.whichwrap
+ end)
+
+ matches(
+ "Invalid option type 'boolean' for 'whichwrap'",
+ pcall_err(exec_lua, [[vim.opt.whichwrap = true]])
+ )
+ matches(
+ "Invalid option type 'number' for 'whichwrap'",
+ pcall_err(exec_lua, [[vim.opt.whichwrap = 2]])
+ )
+ matches(
+ "Invalid option type 'function' for 'whichwrap'",
+ pcall_err(exec_lua, [[vim.opt.whichwrap = function() return "b,s,<,>,[,]" end]])
+ )
+ end)
+ end)
+
+ -- isfname=a,b,c,,,d,e,f
+ it('can handle isfname ,,,', function()
+ eq_exec_lua({ { ',', 'a', 'b', 'c' }, 'a,b,,,c' }, function()
+ vim.opt.isfname = 'a,b,,,c'
+ return { vim.opt.isfname:get(), vim.go.isfname }
+ end)
+ end)
+
+ -- isfname=a,b,c,^,,def
+ it('can handle isfname ,^,,', function()
+ eq_exec_lua({ { '^,', 'a', 'b', 'c' }, 'a,b,^,,c' }, function()
+ vim.opt.isfname = 'a,b,^,,c'
+ return { vim.opt.isfname:get(), vim.go.isfname }
+ end)
+ end)
+
+ describe('https://github.com/neovim/neovim/issues/14828', function()
+ it('gives empty list when item is empty:array', function()
+ eq_exec_lua({}, function()
+ vim.cmd('set wildignore=')
+ return vim.opt.wildignore:get()
+ end)
+
+ eq_exec_lua({}, function()
+ vim.opt.wildignore = {}
+ return vim.opt.wildignore:get()
+ end)
+ end)
+
+ it('gives empty list when item is empty:set', function()
+ eq_exec_lua({}, function()
+ vim.cmd('set formatoptions=')
+ return vim.opt.formatoptions:get()
+ end)
+
+ eq_exec_lua({}, function()
+ vim.opt.formatoptions = {}
+ return vim.opt.formatoptions:get()
+ end)
+ end)
+
+ it('does not append to empty item', function()
+ eq_exec_lua({ '*.foo', '*.bar' }, function()
+ vim.opt.wildignore = {}
+ vim.opt.wildignore:append { '*.foo', '*.bar' }
+ return vim.opt.wildignore:get()
+ end)
+ end)
+
+ it('does not prepend to empty item', function()
+ eq_exec_lua({ '*.foo', '*.bar' }, function()
+ vim.opt.wildignore = {}
+ vim.opt.wildignore:prepend { '*.foo', '*.bar' }
+ return vim.opt.wildignore:get()
+ end)
+ end)
+
+ it('append to empty set', function()
+ eq_exec_lua({ t = true }, function()
+ vim.opt.formatoptions = {}
+ vim.opt.formatoptions:append('t')
+ return vim.opt.formatoptions:get()
+ end)
+ end)
+
+ it('prepend to empty set', function()
+ eq_exec_lua({ t = true }, function()
+ vim.opt.formatoptions = {}
+ vim.opt.formatoptions:prepend('t')
+ return vim.opt.formatoptions:get()
+ end)
+ end)
+ end)
+ end) -- vim.opt
+
+ describe('vim.opt_local', function()
+ it('appends into global value when changing local option value', function()
+ eq_exec_lua('foo,bar,baz,qux', function()
+ vim.opt.tags = 'foo,bar'
+ vim.opt_local.tags:append('baz')
+ vim.opt_local.tags:append('qux')
+ return vim.bo.tags
+ end)
+ end)
+ end)
+
+ describe('vim.opt_global', function()
+ it('gets current global option value', function()
+ eq_exec_lua({ 'yes' }, function()
+ vim.cmd 'setglobal signcolumn=yes'
+ return { vim.opt_global.signcolumn:get() }
+ end)
+ end)
+ end)
+ end)
+
+end)
diff --git a/test/functional/lua/vim_spec.lua b/test/functional/lua/vim_spec.lua
@@ -23,17 +23,10 @@ local NIL = vim.NIL
local retry = t.retry
local next_msg = n.next_msg
local remove_trace = t.remove_trace
-local mkdir_p = n.mkdir_p
-local rmdir = n.rmdir
-local write_file = t.write_file
local poke_eventloop = n.poke_eventloop
local assert_alive = n.assert_alive
local expect = n.expect
-local function eq_exec_lua(expected, f)
- eq(expected, exec_lua(f))
-end
-
describe('lua stdlib', function()
before_each(clear)
-- İ: `tolower("İ")` is `i` which has length 1 while `İ` itself has
@@ -1726,1165 +1719,6 @@ describe('lua stdlib', function()
eq(false, exec_lua('return vim.is_callable({})'))
end)
- it('vim.g', function()
- exec_lua [[
- vim.api.nvim_set_var("testing", "hi")
- vim.api.nvim_set_var("other", 123)
- vim.api.nvim_set_var("floaty", 5120.1)
- vim.api.nvim_set_var("nullvar", vim.NIL)
- vim.api.nvim_set_var("to_delete", {hello="world"})
- ]]
-
- eq('hi', fn.luaeval 'vim.g.testing')
- eq(123, fn.luaeval 'vim.g.other')
- eq(5120.1, fn.luaeval 'vim.g.floaty')
- eq(NIL, fn.luaeval 'vim.g.nonexistent')
- eq(NIL, fn.luaeval 'vim.g.nullvar')
- -- lost over RPC, so test locally:
- eq(
- { false, true },
- exec_lua [[
- return {vim.g.nonexistent == vim.NIL, vim.g.nullvar == vim.NIL}
- ]]
- )
-
- eq({ hello = 'world' }, fn.luaeval 'vim.g.to_delete')
- exec_lua [[
- vim.g.to_delete = nil
- ]]
- eq(NIL, fn.luaeval 'vim.g.to_delete')
-
- matches([[attempt to index .* nil value]], pcall_err(exec_lua, 'return vim.g[0].testing'))
-
- exec_lua [[
- local counter = 0
- local function add_counter() counter = counter + 1 end
- local function get_counter() return counter end
- vim.g.AddCounter = add_counter
- vim.g.GetCounter = get_counter
- vim.g.fn = {add = add_counter, get = get_counter}
- vim.g.AddParens = function(s) return '(' .. s .. ')' end
- ]]
-
- eq(0, eval('g:GetCounter()'))
- eval('g:AddCounter()')
- eq(1, eval('g:GetCounter()'))
- eval('g:AddCounter()')
- eq(2, eval('g:GetCounter()'))
- exec_lua([[vim.g.AddCounter()]])
- eq(3, exec_lua([[return vim.g.GetCounter()]]))
- exec_lua([[vim.api.nvim_get_var('AddCounter')()]])
- eq(4, exec_lua([[return vim.api.nvim_get_var('GetCounter')()]]))
- exec_lua([[vim.g.fn.add()]])
- eq(5, exec_lua([[return vim.g.fn.get()]]))
- exec_lua([[vim.api.nvim_get_var('fn').add()]])
- eq(6, exec_lua([[return vim.api.nvim_get_var('fn').get()]]))
- eq('((foo))', eval([['foo'->AddParens()->AddParens()]]))
-
- exec_lua [[
- local counter = 0
- local function add_counter() counter = counter + 1 end
- local function get_counter() return counter end
- vim.api.nvim_set_var('AddCounter', add_counter)
- vim.api.nvim_set_var('GetCounter', get_counter)
- vim.api.nvim_set_var('fn', {add = add_counter, get = get_counter})
- vim.api.nvim_set_var('AddParens', function(s) return '(' .. s .. ')' end)
- ]]
-
- eq(0, eval('g:GetCounter()'))
- eval('g:AddCounter()')
- eq(1, eval('g:GetCounter()'))
- eval('g:AddCounter()')
- eq(2, eval('g:GetCounter()'))
- exec_lua([[vim.g.AddCounter()]])
- eq(3, exec_lua([[return vim.g.GetCounter()]]))
- exec_lua([[vim.api.nvim_get_var('AddCounter')()]])
- eq(4, exec_lua([[return vim.api.nvim_get_var('GetCounter')()]]))
- exec_lua([[vim.g.fn.add()]])
- eq(5, exec_lua([[return vim.g.fn.get()]]))
- exec_lua([[vim.api.nvim_get_var('fn').add()]])
- eq(6, exec_lua([[return vim.api.nvim_get_var('fn').get()]]))
- eq('((foo))', eval([['foo'->AddParens()->AddParens()]]))
-
- exec([[
- function Test()
- endfunction
- function s:Test()
- endfunction
- let g:Unknown_func = function('Test')
- let g:Unknown_script_func = function('s:Test')
- ]])
- eq(NIL, exec_lua([[return vim.g.Unknown_func]]))
- eq(NIL, exec_lua([[return vim.g.Unknown_script_func]]))
-
- -- Check if autoload works properly
- local pathsep = n.get_pathsep()
- local xconfig = 'Xhome' .. pathsep .. 'Xconfig'
- local xdata = 'Xhome' .. pathsep .. 'Xdata'
- local autoload_folder = table.concat({ xconfig, 'nvim', 'autoload' }, pathsep)
- local autoload_file = table.concat({ autoload_folder, 'testload.vim' }, pathsep)
- mkdir_p(autoload_folder)
- write_file(autoload_file, [[let testload#value = 2]])
-
- clear { args_rm = { '-u' }, env = { XDG_CONFIG_HOME = xconfig, XDG_DATA_HOME = xdata } }
-
- eq(2, exec_lua("return vim.g['testload#value']"))
- rmdir('Xhome')
- end)
-
- it('vim.b', function()
- exec_lua [[
- vim.api.nvim_buf_set_var(0, "testing", "hi")
- vim.api.nvim_buf_set_var(0, "other", 123)
- vim.api.nvim_buf_set_var(0, "floaty", 5120.1)
- vim.api.nvim_buf_set_var(0, "nullvar", vim.NIL)
- vim.api.nvim_buf_set_var(0, "to_delete", {hello="world"})
- BUF = vim.api.nvim_create_buf(false, true)
- vim.api.nvim_buf_set_var(BUF, "testing", "bye")
- ]]
-
- eq('hi', fn.luaeval 'vim.b.testing')
- eq('bye', fn.luaeval 'vim.b[BUF].testing')
- eq(123, fn.luaeval 'vim.b.other')
- eq(5120.1, fn.luaeval 'vim.b.floaty')
- eq(NIL, fn.luaeval 'vim.b.nonexistent')
- eq(NIL, fn.luaeval 'vim.b[BUF].nonexistent')
- eq(NIL, fn.luaeval 'vim.b.nullvar')
- -- lost over RPC, so test locally:
- eq(
- { false, true },
- exec_lua [[
- return {vim.b.nonexistent == vim.NIL, vim.b.nullvar == vim.NIL}
- ]]
- )
-
- matches([[attempt to index .* nil value]], pcall_err(exec_lua, 'return vim.b[BUF][0].testing'))
-
- eq({ hello = 'world' }, fn.luaeval 'vim.b.to_delete')
- exec_lua [[
- vim.b.to_delete = nil
- ]]
- eq(NIL, fn.luaeval 'vim.b.to_delete')
-
- exec_lua [[
- local counter = 0
- local function add_counter() counter = counter + 1 end
- local function get_counter() return counter end
- vim.b.AddCounter = add_counter
- vim.b.GetCounter = get_counter
- vim.b.fn = {add = add_counter, get = get_counter}
- vim.b.AddParens = function(s) return '(' .. s .. ')' end
- ]]
-
- eq(0, eval('b:GetCounter()'))
- eval('b:AddCounter()')
- eq(1, eval('b:GetCounter()'))
- eval('b:AddCounter()')
- eq(2, eval('b:GetCounter()'))
- exec_lua([[vim.b.AddCounter()]])
- eq(3, exec_lua([[return vim.b.GetCounter()]]))
- exec_lua([[vim.api.nvim_buf_get_var(0, 'AddCounter')()]])
- eq(4, exec_lua([[return vim.api.nvim_buf_get_var(0, 'GetCounter')()]]))
- exec_lua([[vim.b.fn.add()]])
- eq(5, exec_lua([[return vim.b.fn.get()]]))
- exec_lua([[vim.api.nvim_buf_get_var(0, 'fn').add()]])
- eq(6, exec_lua([[return vim.api.nvim_buf_get_var(0, 'fn').get()]]))
- eq('((foo))', eval([['foo'->b:AddParens()->b:AddParens()]]))
-
- exec_lua [[
- local counter = 0
- local function add_counter() counter = counter + 1 end
- local function get_counter() return counter end
- vim.api.nvim_buf_set_var(0, 'AddCounter', add_counter)
- vim.api.nvim_buf_set_var(0, 'GetCounter', get_counter)
- vim.api.nvim_buf_set_var(0, 'fn', {add = add_counter, get = get_counter})
- vim.api.nvim_buf_set_var(0, 'AddParens', function(s) return '(' .. s .. ')' end)
- ]]
-
- eq(0, eval('b:GetCounter()'))
- eval('b:AddCounter()')
- eq(1, eval('b:GetCounter()'))
- eval('b:AddCounter()')
- eq(2, eval('b:GetCounter()'))
- exec_lua([[vim.b.AddCounter()]])
- eq(3, exec_lua([[return vim.b.GetCounter()]]))
- exec_lua([[vim.api.nvim_buf_get_var(0, 'AddCounter')()]])
- eq(4, exec_lua([[return vim.api.nvim_buf_get_var(0, 'GetCounter')()]]))
- exec_lua([[vim.b.fn.add()]])
- eq(5, exec_lua([[return vim.b.fn.get()]]))
- exec_lua([[vim.api.nvim_buf_get_var(0, 'fn').add()]])
- eq(6, exec_lua([[return vim.api.nvim_buf_get_var(0, 'fn').get()]]))
- eq('((foo))', eval([['foo'->b:AddParens()->b:AddParens()]]))
-
- exec([[
- function Test()
- endfunction
- function s:Test()
- endfunction
- let b:Unknown_func = function('Test')
- let b:Unknown_script_func = function('s:Test')
- ]])
- eq(NIL, exec_lua([[return vim.b.Unknown_func]]))
- eq(NIL, exec_lua([[return vim.b.Unknown_script_func]]))
-
- exec_lua [[
- vim.cmd "vnew"
- ]]
-
- eq(NIL, fn.luaeval 'vim.b.testing')
- eq(NIL, fn.luaeval 'vim.b.other')
- eq(NIL, fn.luaeval 'vim.b.nonexistent')
- end)
-
- it('vim.w', function()
- exec_lua [[
- vim.api.nvim_win_set_var(0, "testing", "hi")
- vim.api.nvim_win_set_var(0, "other", 123)
- vim.api.nvim_win_set_var(0, "to_delete", {hello="world"})
- BUF = vim.api.nvim_create_buf(false, true)
- WIN = vim.api.nvim_open_win(BUF, false, {
- width=10, height=10,
- relative='win', row=0, col=0
- })
- vim.api.nvim_win_set_var(WIN, "testing", "bye")
- ]]
-
- eq('hi', fn.luaeval 'vim.w.testing')
- eq('bye', fn.luaeval 'vim.w[WIN].testing')
- eq(123, fn.luaeval 'vim.w.other')
- eq(NIL, fn.luaeval 'vim.w.nonexistent')
- eq(NIL, fn.luaeval 'vim.w[WIN].nonexistent')
-
- matches([[attempt to index .* nil value]], pcall_err(exec_lua, 'return vim.w[WIN][0].testing'))
-
- eq({ hello = 'world' }, fn.luaeval 'vim.w.to_delete')
- exec_lua [[
- vim.w.to_delete = nil
- ]]
- eq(NIL, fn.luaeval 'vim.w.to_delete')
-
- exec_lua [[
- local counter = 0
- local function add_counter() counter = counter + 1 end
- local function get_counter() return counter end
- vim.w.AddCounter = add_counter
- vim.w.GetCounter = get_counter
- vim.w.fn = {add = add_counter, get = get_counter}
- vim.w.AddParens = function(s) return '(' .. s .. ')' end
- ]]
-
- eq(0, eval('w:GetCounter()'))
- eval('w:AddCounter()')
- eq(1, eval('w:GetCounter()'))
- eval('w:AddCounter()')
- eq(2, eval('w:GetCounter()'))
- exec_lua([[vim.w.AddCounter()]])
- eq(3, exec_lua([[return vim.w.GetCounter()]]))
- exec_lua([[vim.api.nvim_win_get_var(0, 'AddCounter')()]])
- eq(4, exec_lua([[return vim.api.nvim_win_get_var(0, 'GetCounter')()]]))
- exec_lua([[vim.w.fn.add()]])
- eq(5, exec_lua([[return vim.w.fn.get()]]))
- exec_lua([[vim.api.nvim_win_get_var(0, 'fn').add()]])
- eq(6, exec_lua([[return vim.api.nvim_win_get_var(0, 'fn').get()]]))
- eq('((foo))', eval([['foo'->w:AddParens()->w:AddParens()]]))
-
- exec_lua [[
- local counter = 0
- local function add_counter() counter = counter + 1 end
- local function get_counter() return counter end
- vim.api.nvim_win_set_var(0, 'AddCounter', add_counter)
- vim.api.nvim_win_set_var(0, 'GetCounter', get_counter)
- vim.api.nvim_win_set_var(0, 'fn', {add = add_counter, get = get_counter})
- vim.api.nvim_win_set_var(0, 'AddParens', function(s) return '(' .. s .. ')' end)
- ]]
-
- eq(0, eval('w:GetCounter()'))
- eval('w:AddCounter()')
- eq(1, eval('w:GetCounter()'))
- eval('w:AddCounter()')
- eq(2, eval('w:GetCounter()'))
- exec_lua([[vim.w.AddCounter()]])
- eq(3, exec_lua([[return vim.w.GetCounter()]]))
- exec_lua([[vim.api.nvim_win_get_var(0, 'AddCounter')()]])
- eq(4, exec_lua([[return vim.api.nvim_win_get_var(0, 'GetCounter')()]]))
- exec_lua([[vim.w.fn.add()]])
- eq(5, exec_lua([[return vim.w.fn.get()]]))
- exec_lua([[vim.api.nvim_win_get_var(0, 'fn').add()]])
- eq(6, exec_lua([[return vim.api.nvim_win_get_var(0, 'fn').get()]]))
- eq('((foo))', eval([['foo'->w:AddParens()->w:AddParens()]]))
-
- exec([[
- function Test()
- endfunction
- function s:Test()
- endfunction
- let w:Unknown_func = function('Test')
- let w:Unknown_script_func = function('s:Test')
- ]])
- eq(NIL, exec_lua([[return vim.w.Unknown_func]]))
- eq(NIL, exec_lua([[return vim.w.Unknown_script_func]]))
-
- exec_lua [[
- vim.cmd "vnew"
- ]]
-
- eq(NIL, fn.luaeval 'vim.w.testing')
- eq(NIL, fn.luaeval 'vim.w.other')
- eq(NIL, fn.luaeval 'vim.w.nonexistent')
- end)
-
- it('vim.t', function()
- exec_lua [[
- vim.api.nvim_tabpage_set_var(0, "testing", "hi")
- vim.api.nvim_tabpage_set_var(0, "other", 123)
- vim.api.nvim_tabpage_set_var(0, "to_delete", {hello="world"})
- ]]
-
- eq('hi', fn.luaeval 'vim.t.testing')
- eq(123, fn.luaeval 'vim.t.other')
- eq(NIL, fn.luaeval 'vim.t.nonexistent')
- eq('hi', fn.luaeval 'vim.t[0].testing')
- eq(123, fn.luaeval 'vim.t[0].other')
- eq(NIL, fn.luaeval 'vim.t[0].nonexistent')
-
- matches([[attempt to index .* nil value]], pcall_err(exec_lua, 'return vim.t[0][0].testing'))
-
- eq({ hello = 'world' }, fn.luaeval 'vim.t.to_delete')
- exec_lua [[
- vim.t.to_delete = nil
- ]]
- eq(NIL, fn.luaeval 'vim.t.to_delete')
-
- exec_lua [[
- local counter = 0
- local function add_counter() counter = counter + 1 end
- local function get_counter() return counter end
- vim.t.AddCounter = add_counter
- vim.t.GetCounter = get_counter
- vim.t.fn = {add = add_counter, get = get_counter}
- vim.t.AddParens = function(s) return '(' .. s .. ')' end
- ]]
-
- eq(0, eval('t:GetCounter()'))
- eval('t:AddCounter()')
- eq(1, eval('t:GetCounter()'))
- eval('t:AddCounter()')
- eq(2, eval('t:GetCounter()'))
- exec_lua([[vim.t.AddCounter()]])
- eq(3, exec_lua([[return vim.t.GetCounter()]]))
- exec_lua([[vim.api.nvim_tabpage_get_var(0, 'AddCounter')()]])
- eq(4, exec_lua([[return vim.api.nvim_tabpage_get_var(0, 'GetCounter')()]]))
- exec_lua([[vim.t.fn.add()]])
- eq(5, exec_lua([[return vim.t.fn.get()]]))
- exec_lua([[vim.api.nvim_tabpage_get_var(0, 'fn').add()]])
- eq(6, exec_lua([[return vim.api.nvim_tabpage_get_var(0, 'fn').get()]]))
- eq('((foo))', eval([['foo'->t:AddParens()->t:AddParens()]]))
-
- exec_lua [[
- local counter = 0
- local function add_counter() counter = counter + 1 end
- local function get_counter() return counter end
- vim.api.nvim_tabpage_set_var(0, 'AddCounter', add_counter)
- vim.api.nvim_tabpage_set_var(0, 'GetCounter', get_counter)
- vim.api.nvim_tabpage_set_var(0, 'fn', {add = add_counter, get = get_counter})
- vim.api.nvim_tabpage_set_var(0, 'AddParens', function(s) return '(' .. s .. ')' end)
- ]]
-
- eq(0, eval('t:GetCounter()'))
- eval('t:AddCounter()')
- eq(1, eval('t:GetCounter()'))
- eval('t:AddCounter()')
- eq(2, eval('t:GetCounter()'))
- exec_lua([[vim.t.AddCounter()]])
- eq(3, exec_lua([[return vim.t.GetCounter()]]))
- exec_lua([[vim.api.nvim_tabpage_get_var(0, 'AddCounter')()]])
- eq(4, exec_lua([[return vim.api.nvim_tabpage_get_var(0, 'GetCounter')()]]))
- exec_lua([[vim.t.fn.add()]])
- eq(5, exec_lua([[return vim.t.fn.get()]]))
- exec_lua([[vim.api.nvim_tabpage_get_var(0, 'fn').add()]])
- eq(6, exec_lua([[return vim.api.nvim_tabpage_get_var(0, 'fn').get()]]))
- eq('((foo))', eval([['foo'->t:AddParens()->t:AddParens()]]))
-
- exec_lua [[
- vim.cmd "tabnew"
- ]]
-
- eq(NIL, fn.luaeval 'vim.t.testing')
- eq(NIL, fn.luaeval 'vim.t.other')
- eq(NIL, fn.luaeval 'vim.t.nonexistent')
- end)
-
- it('vim.env', function()
- exec_lua([[vim.fn.setenv('A', 123)]])
- eq('123', fn.luaeval('vim.env.A'))
- exec_lua([[vim.env.A = 456]])
- eq('456', fn.luaeval('vim.env.A'))
- exec_lua([[vim.env.A = nil]])
- eq(NIL, fn.luaeval('vim.env.A'))
-
- eq(true, fn.luaeval('vim.env.B == nil'))
-
- command([[let $HOME = 'foo']])
- eq('foo', fn.expand('~'))
- eq('foo', fn.luaeval('vim.env.HOME'))
- exec_lua([[vim.env.HOME = nil]])
- eq('foo', fn.expand('~'))
- exec_lua([[vim.env.HOME = 'bar']])
- eq('bar', fn.expand('~'))
- eq('bar', fn.luaeval('vim.env.HOME'))
- end)
-
- it('vim.v', function()
- eq(fn.luaeval "vim.api.nvim_get_vvar('progpath')", fn.luaeval 'vim.v.progpath')
- eq(false, fn.luaeval "vim.v['false']")
- eq(NIL, fn.luaeval 'vim.v.null')
- matches([[attempt to index .* nil value]], pcall_err(exec_lua, 'return vim.v[0].progpath'))
- matches('Key is read%-only: count$', pcall_err(exec_lua, [[vim.v.count = 42]]))
- matches('Dict is locked$', pcall_err(exec_lua, [[vim.v.nosuchvar = 42]]))
- matches('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'))
- matches(
- '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 }, api.nvim_win_get_cursor(0))
- eq(1, eval('v:searchforward'))
- feed('n')
- eq({ 1, 5 }, api.nvim_win_get_cursor(0))
- exec_lua([[vim.v.searchforward = 0]])
- eq(0, eval('v:searchforward'))
- feed('n')
- eq({ 1, 1 }, api.nvim_win_get_cursor(0))
- exec_lua([[vim.v.searchforward = 1]])
- eq(1, eval('v:searchforward'))
- feed('n')
- eq({ 1, 5 }, api.nvim_win_get_cursor(0))
-
- local screen = Screen.new(60, 3)
- eq(1, eval('v:hlsearch'))
- screen:expect {
- grid = [[
- {10:foo} {10:^foo} {10:foo} |
- {1:~ }|
- |
- ]],
- }
- exec_lua([[vim.v.hlsearch = 0]])
- eq(0, eval('v:hlsearch'))
- screen:expect {
- grid = [[
- foo ^foo foo |
- {1:~ }|
- |
- ]],
- }
- exec_lua([[vim.v.hlsearch = 1]])
- eq(1, eval('v:hlsearch'))
- screen:expect {
- grid = [[
- {10:foo} {10:^foo} {10:foo} |
- {1:~ }|
- |
- ]],
- }
- end)
-
- it('vim.bo', function()
- eq('', fn.luaeval 'vim.bo.filetype')
- exec_lua(function()
- _G.BUF = vim.api.nvim_create_buf(false, true)
- vim.api.nvim_set_option_value('filetype', 'markdown', {})
- vim.api.nvim_set_option_value('modifiable', false, { buf = _G.BUF })
- end)
- eq(false, fn.luaeval 'vim.bo.modified')
- eq('markdown', fn.luaeval 'vim.bo.filetype')
- eq(false, fn.luaeval 'vim.bo[BUF].modifiable')
- exec_lua(function()
- vim.bo.filetype = ''
- vim.bo[_G.BUF].modifiable = true
- end)
- eq('', fn.luaeval 'vim.bo.filetype')
- eq(true, fn.luaeval 'vim.bo[BUF].modifiable')
- matches("Unknown option 'nosuchopt'$", pcall_err(exec_lua, 'return vim.bo.nosuchopt'))
- 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'))
- end)
-
- it('vim.wo', function()
- exec_lua(function()
- vim.api.nvim_set_option_value('cole', 2, {})
- vim.cmd 'split'
- vim.api.nvim_set_option_value('cole', 2, {})
- end)
- eq(2, fn.luaeval 'vim.wo.cole')
- exec_lua(function()
- vim.wo.conceallevel = 0
- end)
- eq(0, fn.luaeval 'vim.wo.cole')
- eq(0, fn.luaeval 'vim.wo[0].cole')
- eq(0, fn.luaeval 'vim.wo[1001].cole')
- matches("Unknown option 'notanopt'$", pcall_err(exec_lua, 'return vim.wo.notanopt'))
- matches('Invalid window id: %-1$', pcall_err(exec_lua, 'return vim.wo[-1].list'))
- eq(2, fn.luaeval 'vim.wo[1000].cole')
- exec_lua(function()
- vim.wo[1000].cole = 0
- end)
- eq(0, fn.luaeval 'vim.wo[1000].cole')
-
- -- Can handle global-local values
- exec_lua [[vim.o.scrolloff = 100]]
- exec_lua [[vim.wo.scrolloff = 200]]
- eq(200, fn.luaeval 'vim.wo.scrolloff')
- exec_lua [[vim.wo.scrolloff = -1]]
- eq(100, fn.luaeval 'vim.wo.scrolloff')
- exec_lua(function()
- vim.wo[0][0].scrolloff = 200
- vim.cmd 'enew'
- end)
- eq(100, fn.luaeval 'vim.wo.scrolloff')
-
- matches('only bufnr=0 is supported', pcall_err(exec_lua, 'vim.wo[0][10].signcolumn = "no"'))
-
- matches('only bufnr=0 is supported', pcall_err(exec_lua, 'local a = vim.wo[0][10].signcolumn'))
- end)
-
- describe('vim.opt', function()
- -- TODO: We still need to write some tests for optlocal, opt and then getting the options
- -- Probably could also do some stuff with getting things from viml side as well to confirm behavior is the same.
-
- it('allows setting number values', function()
- local scrolloff = exec_lua [[
- vim.opt.scrolloff = 10
- return vim.o.scrolloff
- ]]
- eq(10, scrolloff)
- end)
-
- pending('handles STUPID window things', function()
- eq_exec_lua({}, function()
- return {
- vim.api.nvim_get_option_value('scrolloff', { scope = 'global' }),
- vim.api.nvim_get_option_value('scrolloff', { win = 0 }),
- }
- end)
- end)
-
- it('allows setting tables', function()
- eq_exec_lua('hello,world', function()
- vim.opt.wildignore = { 'hello', 'world' }
- return vim.o.wildignore
- end)
- end)
-
- it('allows setting tables with shortnames', function()
- eq_exec_lua('hello,world', function()
- vim.opt.wig = { 'hello', 'world' }
- return vim.o.wildignore
- end)
- end)
-
- it('errors when you attempt to set string values to numeric options', function()
- eq_exec_lua(false, function()
- return ({
- pcall(function()
- vim.opt.textwidth = 'hello world'
- end),
- })[1]
- end)
- end)
-
- it('errors when you attempt to setlocal a global value', function()
- eq_exec_lua(false, function()
- return pcall(function()
- vim.opt_local.clipboard = 'hello'
- end)
- end)
- end)
-
- it('allows you to set boolean values', function()
- eq_exec_lua({ true, false, true }, function()
- local results = {}
-
- vim.opt.autoindent = true
- table.insert(results, vim.bo.autoindent)
-
- vim.opt.autoindent = false
- table.insert(results, vim.bo.autoindent)
-
- vim.opt.autoindent = not vim.opt.autoindent:get()
- table.insert(results, vim.bo.autoindent)
-
- return results
- end)
- end)
-
- it('changes current buffer values and defaults for global local values', function()
- local result = exec_lua(function()
- local result = {}
-
- vim.opt.makeprg = 'global-local'
- 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.go.makeprg)
- table.insert(result, vim.api.nvim_get_option_value('makeprg', { buf = 0 }))
-
- vim.opt_global.makeprg = 'only-global'
- 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.go.makeprg)
- table.insert(result, vim.api.nvim_get_option_value('makeprg', { buf = 0 }))
- return result
- end)
-
- -- Set -> global & local
- eq('global-local', result[1])
- eq('', result[2])
-
- -- Setlocal -> only local
- eq('global-local', result[3])
- eq('only-local', result[4])
-
- -- Setglobal -> only global
- eq('only-global', result[5])
- eq('only-local', result[6])
-
- -- Set -> sets global value and resets local value
- eq('global-local', result[7])
- eq('', result[8])
- end)
-
- it('allows you to retrieve window opts even if they have not been set', function()
- eq_exec_lua({ false, false, true, true }, function()
- local result = {}
- table.insert(result, vim.opt.number:get())
- table.insert(result, vim.opt_local.number:get())
-
- vim.opt_local.number = true
- table.insert(result, vim.opt.number:get())
- table.insert(result, vim.opt_local.number:get())
-
- return result
- end)
- end)
-
- it('allows all sorts of string manipulation', function()
- eq_exec_lua({ 'hello', 'hello world', 'start hello world' }, function()
- local results = {}
-
- vim.opt.makeprg = 'hello'
- table.insert(results, vim.o.makeprg)
-
- vim.opt.makeprg = vim.opt.makeprg + ' world'
- table.insert(results, vim.o.makeprg)
-
- vim.opt.makeprg = vim.opt.makeprg ^ 'start '
- table.insert(results, vim.o.makeprg)
-
- return results
- end)
- end)
-
- describe('option:get()', function()
- it('works for boolean values', function()
- eq_exec_lua(false, function()
- vim.opt.number = false
- return vim.opt.number:get()
- end)
- end)
-
- it('works for number values', function()
- eq_exec_lua(10, function()
- vim.opt.tabstop = 10
- return vim.opt.tabstop:get()
- end)
- end)
-
- it('works for string values', function()
- eq_exec_lua('hello world', function()
- vim.opt.makeprg = 'hello world'
- return vim.opt.makeprg:get()
- end)
- end)
-
- it('works for set type flaglists', function()
- local formatoptions = exec_lua(function()
- vim.opt.formatoptions = 'tcro'
- return vim.opt.formatoptions:get()
- end)
-
- eq(true, formatoptions.t)
- eq(true, not formatoptions.q)
- end)
-
- it('works for set type flaglists', function()
- local formatoptions = exec_lua(function()
- vim.opt.formatoptions = { t = true, c = true, r = true, o = true }
- return vim.opt.formatoptions:get()
- end)
-
- eq(true, formatoptions.t)
- eq(true, not formatoptions.q)
- end)
-
- it('works for array list type options', function()
- local wildignore = exec_lua(function()
- vim.opt.wildignore = '*.c,*.o,__pycache__'
- return vim.opt.wildignore:get()
- end)
-
- eq(3, #wildignore)
- eq('*.c', wildignore[1])
- end)
-
- it('works for options that are both commalist and flaglist', function()
- eq_exec_lua({ b = true, s = true }, function()
- vim.opt.whichwrap = 'b,s'
- return vim.opt.whichwrap:get()
- end)
-
- eq_exec_lua({ b = true, h = true }, function()
- vim.opt.whichwrap = { b = true, s = false, h = true }
- return vim.opt.whichwrap:get()
- end)
- end)
-
- it('works for key-value pair options', function()
- eq_exec_lua({ tab = '> ', space = '_' }, function()
- vim.opt.listchars = 'tab:> ,space:_'
- return vim.opt.listchars:get()
- end)
- end)
-
- it('allows you to add numeric options', function()
- eq_exec_lua(16, function()
- vim.opt.tabstop = 12
- vim.opt.tabstop = vim.opt.tabstop + 4
- return vim.bo.tabstop
- end)
- end)
-
- it('allows you to subtract numeric options', function()
- eq_exec_lua(2, function()
- vim.opt.tabstop = 4
- vim.opt.tabstop = vim.opt.tabstop - 2
- return vim.bo.tabstop
- end)
- end)
- end)
-
- describe('key:value style options', function()
- it('handles dict style', function()
- eq_exec_lua('eol:~,space:.', function()
- vim.opt.listchars = { eol = '~', space = '.' }
- return vim.o.listchars
- end)
- end)
-
- it('allows adding dict style', function()
- eq_exec_lua('eol:~,space:-', function()
- vim.opt.listchars = { eol = '~', space = '.' }
- vim.opt.listchars = vim.opt.listchars + { space = '-' }
- return vim.o.listchars
- end)
- end)
-
- it('allows adding dict style', function()
- eq_exec_lua('eol:~,space:_', function()
- vim.opt.listchars = { eol = '~', space = '.' }
- vim.opt.listchars = vim.opt.listchars + { space = '-' } + { space = '_' }
- return vim.o.listchars
- end)
- end)
-
- it('allows completely new keys', function()
- eq_exec_lua('eol:~,space:.,tab:>>>', function()
- vim.opt.listchars = { eol = '~', space = '.' }
- vim.opt.listchars = vim.opt.listchars + { tab = '>>>' }
- return vim.o.listchars
- end)
- end)
-
- it('allows subtracting dict style', function()
- eq_exec_lua('eol:~', function()
- vim.opt.listchars = { eol = '~', space = '.' }
- vim.opt.listchars = vim.opt.listchars - 'space'
- return vim.o.listchars
- end)
- end)
-
- it('allows subtracting dict style', function()
- eq_exec_lua('', function()
- vim.opt.listchars = { eol = '~', space = '.' }
- vim.opt.listchars = vim.opt.listchars - 'space' - 'eol'
- return vim.o.listchars
- end)
- end)
-
- it('allows subtracting dict style multiple times', function()
- eq_exec_lua('eol:~', function()
- vim.opt.listchars = { eol = '~', space = '.' }
- vim.opt.listchars = vim.opt.listchars - 'space' - 'space'
- return vim.o.listchars
- end)
- end)
-
- it('allows adding a key:value string to a listchars', function()
- eq_exec_lua('eol:~,space:.,tab:>~', function()
- vim.opt.listchars = { eol = '~', space = '.' }
- vim.opt.listchars = vim.opt.listchars + 'tab:>~'
- return vim.o.listchars
- end)
- end)
-
- it('allows prepending a key:value string to a listchars', function()
- eq_exec_lua('eol:~,space:.,tab:>~', function()
- vim.opt.listchars = { eol = '~', space = '.' }
- vim.opt.listchars = vim.opt.listchars ^ 'tab:>~'
- return vim.o.listchars
- end)
- end)
- end)
-
- it('automatically sets when calling remove', function()
- eq_exec_lua('foo,baz', function()
- vim.opt.wildignore = 'foo,bar,baz'
- vim.opt.wildignore:remove('bar')
- return vim.o.wildignore
- end)
- end)
-
- it('automatically sets when calling remove with a table', function()
- eq_exec_lua('foo', function()
- vim.opt.wildignore = 'foo,bar,baz'
- vim.opt.wildignore:remove { 'bar', 'baz' }
- return vim.o.wildignore
- end)
- end)
-
- it('automatically sets when calling append', function()
- eq_exec_lua('foo,bar,baz,bing', function()
- vim.opt.wildignore = 'foo,bar,baz'
- vim.opt.wildignore:append('bing')
- return vim.o.wildignore
- end)
- end)
-
- it('automatically sets when calling append with a table', function()
- eq_exec_lua('foo,bar,baz,bing,zap', function()
- vim.opt.wildignore = 'foo,bar,baz'
- vim.opt.wildignore:append { 'bing', 'zap' }
- return vim.o.wildignore
- end)
- end)
-
- it('allows adding tables', function()
- eq_exec_lua('foo', function()
- vim.opt.wildignore = 'foo'
- return vim.o.wildignore
- end)
-
- eq_exec_lua('foo,bar,baz', function()
- vim.opt.wildignore = vim.opt.wildignore + { 'bar', 'baz' }
- return vim.o.wildignore
- end)
- end)
-
- it('handles adding duplicates', function()
- eq_exec_lua('foo', function()
- vim.opt.wildignore = 'foo'
- return vim.o.wildignore
- end)
-
- eq_exec_lua('foo,bar,baz', function()
- vim.opt.wildignore = vim.opt.wildignore + { 'bar', 'baz' }
- return vim.o.wildignore
- end)
-
- eq_exec_lua('foo,bar,baz', function()
- vim.opt.wildignore = vim.opt.wildignore + { 'bar', 'baz' }
- return vim.o.wildignore
- end)
- end)
-
- it('allows adding multiple times', function()
- eq_exec_lua('foo,bar,baz', function()
- vim.opt.wildignore = 'foo'
- vim.opt.wildignore = vim.opt.wildignore + 'bar' + 'baz'
- return vim.o.wildignore
- end)
- end)
-
- it('removes values when you use minus', function()
- eq_exec_lua('foo', function()
- vim.opt.wildignore = 'foo'
- return vim.o.wildignore
- end)
-
- eq_exec_lua('foo,bar,baz', function()
- vim.opt.wildignore = vim.opt.wildignore + { 'bar', 'baz' }
- return vim.o.wildignore
- end)
-
- eq_exec_lua('foo,baz', function()
- vim.opt.wildignore = vim.opt.wildignore - 'bar'
- return vim.o.wildignore
- end)
- end)
-
- it('prepends values when using ^', function()
- eq_exec_lua('first,foo', function()
- vim.opt.wildignore = 'foo'
- vim.opt.wildignore = vim.opt.wildignore ^ 'first'
- return vim.o.wildignore
- end)
-
- eq_exec_lua('super_first,first,foo', function()
- vim.opt.wildignore = vim.opt.wildignore ^ 'super_first'
- return vim.o.wildignore
- end)
- end)
-
- it('does not remove duplicates from wildmode: #14708', function()
- eq_exec_lua('full,list,full', function()
- vim.opt.wildmode = { 'full', 'list', 'full' }
- return vim.o.wildmode
- end)
- end)
-
- describe('option types', function()
- it('allows to set option with numeric value', function()
- eq_exec_lua(4, function()
- vim.opt.tabstop = 4
- return vim.bo.tabstop
- end)
-
- matches(
- "Invalid option type 'string' for 'tabstop'",
- pcall_err(exec_lua, [[vim.opt.tabstop = '4']])
- )
- matches(
- "Invalid option type 'boolean' for 'tabstop'",
- pcall_err(exec_lua, [[vim.opt.tabstop = true]])
- )
- matches(
- "Invalid option type 'table' for 'tabstop'",
- pcall_err(exec_lua, [[vim.opt.tabstop = {4, 2}]])
- )
- matches(
- "Invalid option type 'function' for 'tabstop'",
- pcall_err(exec_lua, [[vim.opt.tabstop = function() return 4 end]])
- )
- end)
-
- it('allows to set option with boolean value', function()
- eq_exec_lua(true, function()
- vim.opt.undofile = true
- return vim.bo.undofile
- end)
-
- matches(
- "Invalid option type 'number' for 'undofile'",
- pcall_err(exec_lua, [[vim.opt.undofile = 0]])
- )
- matches(
- "Invalid option type 'table' for 'undofile'",
- pcall_err(exec_lua, [[vim.opt.undofile = {true}]])
- )
- matches(
- "Invalid option type 'string' for 'undofile'",
- pcall_err(exec_lua, [[vim.opt.undofile = 'true']])
- )
- matches(
- "Invalid option type 'function' for 'undofile'",
- pcall_err(exec_lua, [[vim.opt.undofile = function() return true end]])
- )
- end)
-
- it('allows to set option with array or string value', function()
- eq_exec_lua('indent,eol,start', function()
- vim.opt.backspace = { 'indent', 'eol', 'start' }
- return vim.go.backspace
- end)
-
- eq_exec_lua('indent,eol,start', function()
- vim.opt.backspace = 'indent,eol,start'
- return vim.go.backspace
- end)
-
- matches(
- "Invalid option type 'boolean' for 'backspace'",
- pcall_err(exec_lua, [[vim.opt.backspace = true]])
- )
- matches(
- "Invalid option type 'number' for 'backspace'",
- pcall_err(exec_lua, [[vim.opt.backspace = 2]])
- )
- matches(
- "Invalid option type 'function' for 'backspace'",
- pcall_err(exec_lua, [[vim.opt.backspace = function() return 'indent,eol,start' end]])
- )
- end)
-
- it('allows set option with map or string value', function()
- eq_exec_lua('eol:~,space:.', function()
- vim.opt.listchars = { eol = '~', space = '.' }
- return vim.o.listchars
- end)
-
- eq_exec_lua('eol:~,space:.,tab:>~', function()
- vim.opt.listchars = 'eol:~,space:.,tab:>~'
- return vim.o.listchars
- end)
-
- matches(
- "Invalid option type 'boolean' for 'listchars'",
- pcall_err(exec_lua, [[vim.opt.listchars = true]])
- )
- matches(
- "Invalid option type 'number' for 'listchars'",
- pcall_err(exec_lua, [[vim.opt.listchars = 2]])
- )
- matches(
- "Invalid option type 'function' for 'listchars'",
- pcall_err(exec_lua, [[vim.opt.listchars = function() return "eol:~,space:.,tab:>~" end]])
- )
- end)
-
- it('allows set option with set or string value', function()
- eq_exec_lua('b,s', function()
- vim.opt.whichwrap = { b = true, s = 1 }
- return vim.go.whichwrap
- end)
-
- eq_exec_lua('b,s,<,>,[,]', function()
- vim.opt.whichwrap = 'b,s,<,>,[,]'
- return vim.go.whichwrap
- end)
-
- matches(
- "Invalid option type 'boolean' for 'whichwrap'",
- pcall_err(exec_lua, [[vim.opt.whichwrap = true]])
- )
- matches(
- "Invalid option type 'number' for 'whichwrap'",
- pcall_err(exec_lua, [[vim.opt.whichwrap = 2]])
- )
- matches(
- "Invalid option type 'function' for 'whichwrap'",
- pcall_err(exec_lua, [[vim.opt.whichwrap = function() return "b,s,<,>,[,]" end]])
- )
- end)
- end)
-
- -- isfname=a,b,c,,,d,e,f
- it('can handle isfname ,,,', function()
- eq_exec_lua({ { ',', 'a', 'b', 'c' }, 'a,b,,,c' }, function()
- vim.opt.isfname = 'a,b,,,c'
- return { vim.opt.isfname:get(), vim.go.isfname }
- end)
- end)
-
- -- isfname=a,b,c,^,,def
- it('can handle isfname ,^,,', function()
- eq_exec_lua({ { '^,', 'a', 'b', 'c' }, 'a,b,^,,c' }, function()
- vim.opt.isfname = 'a,b,^,,c'
- return { vim.opt.isfname:get(), vim.go.isfname }
- end)
- end)
-
- describe('https://github.com/neovim/neovim/issues/14828', function()
- it('gives empty list when item is empty:array', function()
- eq_exec_lua({}, function()
- vim.cmd('set wildignore=')
- return vim.opt.wildignore:get()
- end)
-
- eq_exec_lua({}, function()
- vim.opt.wildignore = {}
- return vim.opt.wildignore:get()
- end)
- end)
-
- it('gives empty list when item is empty:set', function()
- eq_exec_lua({}, function()
- vim.cmd('set formatoptions=')
- return vim.opt.formatoptions:get()
- end)
-
- eq_exec_lua({}, function()
- vim.opt.formatoptions = {}
- return vim.opt.formatoptions:get()
- end)
- end)
-
- it('does not append to empty item', function()
- eq_exec_lua({ '*.foo', '*.bar' }, function()
- vim.opt.wildignore = {}
- vim.opt.wildignore:append { '*.foo', '*.bar' }
- return vim.opt.wildignore:get()
- end)
- end)
-
- it('does not prepend to empty item', function()
- eq_exec_lua({ '*.foo', '*.bar' }, function()
- vim.opt.wildignore = {}
- vim.opt.wildignore:prepend { '*.foo', '*.bar' }
- return vim.opt.wildignore:get()
- end)
- end)
-
- it('append to empty set', function()
- eq_exec_lua({ t = true }, function()
- vim.opt.formatoptions = {}
- vim.opt.formatoptions:append('t')
- return vim.opt.formatoptions:get()
- end)
- end)
-
- it('prepend to empty set', function()
- eq_exec_lua({ t = true }, function()
- vim.opt.formatoptions = {}
- vim.opt.formatoptions:prepend('t')
- return vim.opt.formatoptions:get()
- end)
- end)
- end)
- end) -- vim.opt
-
- describe('vim.opt_local', function()
- it('appends into global value when changing local option value', function()
- eq_exec_lua('foo,bar,baz,qux', function()
- vim.opt.tags = 'foo,bar'
- vim.opt_local.tags:append('baz')
- vim.opt_local.tags:append('qux')
- return vim.bo.tags
- end)
- end)
- end)
-
- describe('vim.opt_global', function()
- it('gets current global option value', function()
- eq_exec_lua({ 'yes' }, function()
- vim.cmd 'setglobal signcolumn=yes'
- return { vim.opt_global.signcolumn:get() }
- end)
- end)
- end)
-
it('vim.cmd', function()
exec_lua [[
vim.cmd "autocmd BufNew * ++once lua BUF = vim.fn.expand('<abuf>')"